Commit 0ea99bc16012e45ef9435ecd9fca5a159dadf0e9

Authored by Yarik
1 parent 2f25da09

Test change

Showing 133 changed files with 0 additions and 6475 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 133 files are displayed.

artbox-ecommerce/Module.php renamed to Module.php
artbox-blog deleted
1 -Subproject commit 6813d2d0b71aba72d5c8e6dfdcb7f13aa3791772  
artbox-comment deleted
1 -Subproject commit a2cde075db985ec267c8d896e5abb034a750930e  
artbox-file/FileUploadAsset.php deleted
1 -<?php  
2 -/**  
3 - * @link http://www.yiiframework.com/  
4 - * @copyright Copyright (c) 2008 Yii Software LLC  
5 - * @license http://www.yiiframework.com/license/  
6 - */  
7 -  
8 -  
9 -namespace artweb\artbox\file;  
10 -  
11 -use yii\helpers\Url;  
12 -use yii\web\AssetBundle;  
13 -  
14 -/**  
15 - * Asset bundle for the Twitter bootstrap javascript files.  
16 - *  
17 - * @author Qiang Xue <qiang.xue@gmail.com>  
18 - * @since 2.0  
19 - */  
20 -class FileUploadAsset extends AssetBundle  
21 -{  
22 -  
23 -  
24 - /**  
25 - * @inheritdoc  
26 - */  
27 - public function init()  
28 - {  
29 - parent::init();  
30 - $this->sourcePath = __DIR__.'/assets';  
31 - }  
32 -  
33 - public $css = [  
34 - 'css/jquery.fileupload.css',  
35 - 'css/fileupload/style.css'  
36 - ];  
37 -  
38 - public $js = [  
39 - 'js/vendor/jquery.ui.widget.js',  
40 - 'js/jquery.iframe-transport.js',  
41 - 'js/jquery.fileupload.js'  
42 - ];  
43 -}  
artbox-file/Module.php deleted
1 -<?php  
2 -namespace artweb\artbox\file;  
3 -  
4 -use yii\base\BootstrapInterface;  
5 -  
6 -class Module extends \yii\base\Module  
7 -{  
8 - public function init()  
9 - {  
10 - parent::init();  
11 -  
12 - \Yii::configure($this, require(__DIR__.'/config.php'));  
13 - }  
14 -  
15 -}  
artbox-file/assets/css/fileupload/style.css deleted
1 -.remover_image {  
2 - position: absolute !important;  
3 - font-size: 20px;  
4 - right: 30px;  
5 - top:30px;  
6 - cursor:pointer;  
7 -}  
artbox-file/assets/css/jquery.fileupload-noscript.css deleted
1 -@charset "UTF-8";  
2 -/*  
3 - * jQuery File Upload Plugin NoScript CSS  
4 - * https://github.com/blueimp/jQuery-File-Upload  
5 - *  
6 - * Copyright 2013, Sebastian Tschan  
7 - * https://blueimp.net  
8 - *  
9 - * Licensed under the MIT license:  
10 - * http://www.opensource.org/licenses/MIT  
11 - */  
12 -  
13 -.fileinput-button input {  
14 - position: static;  
15 - opacity: 1;  
16 - filter: none;  
17 - font-size: inherit;  
18 - direction: inherit;  
19 -}  
20 -.fileinput-button span {  
21 - display: none;  
22 -}  
artbox-file/assets/css/jquery.fileupload-ui-noscript.css deleted
1 -@charset "UTF-8";  
2 -/*  
3 - * jQuery File Upload UI Plugin NoScript CSS  
4 - * https://github.com/blueimp/jQuery-File-Upload  
5 - *  
6 - * Copyright 2012, Sebastian Tschan  
7 - * https://blueimp.net  
8 - *  
9 - * Licensed under the MIT license:  
10 - * http://www.opensource.org/licenses/MIT  
11 - */  
12 -  
13 -.fileinput-button i,  
14 -.fileupload-buttonbar .delete,  
15 -.fileupload-buttonbar .toggle {  
16 - display: none;  
17 -}  
artbox-file/assets/css/jquery.fileupload-ui.css deleted
1 -@charset "UTF-8";  
2 -/*  
3 - * jQuery File Upload UI Plugin CSS  
4 - * https://github.com/blueimp/jQuery-File-Upload  
5 - *  
6 - * Copyright 2010, Sebastian Tschan  
7 - * https://blueimp.net  
8 - *  
9 - * Licensed under the MIT license:  
10 - * http://www.opensource.org/licenses/MIT  
11 - */  
12 -  
13 -.fileupload-buttonbar .btn,  
14 -.fileupload-buttonbar .toggle {  
15 - margin-bottom: 5px;  
16 -}  
17 -.progress-animated .progress-bar,  
18 -.progress-animated .bar {  
19 - background: url("../img/progressbar.gif") !important;  
20 - filter: none;  
21 -}  
22 -.fileupload-process {  
23 - float: right;  
24 - display: none;  
25 -}  
26 -.fileupload-processing .fileupload-process,  
27 -.files .processing .preview {  
28 - display: block;  
29 - width: 32px;  
30 - height: 32px;  
31 - background: url("../img/loading.gif") center no-repeat;  
32 - background-size: contain;  
33 -}  
34 -.files audio,  
35 -.files video {  
36 - max-width: 300px;  
37 -}  
38 -  
39 -@media (max-width: 767px) {  
40 - .fileupload-buttonbar .toggle,  
41 - .files .toggle,  
42 - .files .btn span {  
43 - display: none;  
44 - }  
45 - .files .name {  
46 - width: 80px;  
47 - word-wrap: break-word;  
48 - }  
49 - .files audio,  
50 - .files video {  
51 - max-width: 80px;  
52 - }  
53 - .files img,  
54 - .files canvas {  
55 - max-width: 100%;  
56 - }  
57 -}  
artbox-file/assets/css/jquery.fileupload.css deleted
1 -@charset "UTF-8";  
2 -/*  
3 - * jQuery File Upload Plugin CSS  
4 - * https://github.com/blueimp/jQuery-File-Upload  
5 - *  
6 - * Copyright 2013, Sebastian Tschan  
7 - * https://blueimp.net  
8 - *  
9 - * Licensed under the MIT license:  
10 - * http://www.opensource.org/licenses/MIT  
11 - */  
12 -  
13 -.fileinput-button {  
14 - position: relative;  
15 - overflow: hidden;  
16 - display: inline-block;  
17 -}  
18 -.fileinput-button input {  
19 - position: absolute;  
20 - top: 0;  
21 - right: 0;  
22 - margin: 0;  
23 - opacity: 0;  
24 - -ms-filter: 'alpha(opacity=0)';  
25 - font-size: 200px;  
26 - direction: ltr;  
27 - cursor: pointer;  
28 -}  
29 -  
30 -/* Fixes for IE < 8 */  
31 -@media screen\9 {  
32 - .fileinput-button input {  
33 - filter: alpha(opacity=0);  
34 - font-size: 100%;  
35 - height: 100%;  
36 - }  
37 -}  
artbox-file/assets/img/loading.gif deleted

3.81 KB

artbox-file/assets/img/progressbar.gif deleted

3.25 KB

artbox-file/assets/js/cors/jquery.postmessage-transport.js deleted
1 -/*  
2 - * jQuery postMessage Transport Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2011, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* global define, require, window, document */  
13 -  
14 -(function (factory) {  
15 - 'use strict';  
16 - if (typeof define === 'function' && define.amd) {  
17 - // Register as an anonymous AMD module:  
18 - define(['jquery'], factory);  
19 - } else if (typeof exports === 'object') {  
20 - // Node/CommonJS:  
21 - factory(require('jquery'));  
22 - } else {  
23 - // Browser globals:  
24 - factory(window.jQuery);  
25 - }  
26 -}(function ($) {  
27 - 'use strict';  
28 -  
29 - var counter = 0,  
30 - names = [  
31 - 'accepts',  
32 - 'cache',  
33 - 'contents',  
34 - 'contentType',  
35 - 'crossDomain',  
36 - 'data',  
37 - 'dataType',  
38 - 'headers',  
39 - 'ifModified',  
40 - 'mimeType',  
41 - 'password',  
42 - 'processData',  
43 - 'timeout',  
44 - 'traditional',  
45 - 'type',  
46 - 'url',  
47 - 'username'  
48 - ],  
49 - convert = function (p) {  
50 - return p;  
51 - };  
52 -  
53 - $.ajaxSetup({  
54 - converters: {  
55 - 'postmessage text': convert,  
56 - 'postmessage json': convert,  
57 - 'postmessage html': convert  
58 - }  
59 - });  
60 -  
61 - $.ajaxTransport('postmessage', function (options) {  
62 - if (options.postMessage && window.postMessage) {  
63 - var iframe,  
64 - loc = $('<a>').prop('href', options.postMessage)[0],  
65 - target = loc.protocol + '//' + loc.host,  
66 - xhrUpload = options.xhr().upload;  
67 - return {  
68 - send: function (_, completeCallback) {  
69 - counter += 1;  
70 - var message = {  
71 - id: 'postmessage-transport-' + counter  
72 - },  
73 - eventName = 'message.' + message.id;  
74 - iframe = $(  
75 - '<iframe style="display:none;" src="' +  
76 - options.postMessage + '" name="' +  
77 - message.id + '"></iframe>'  
78 - ).bind('load', function () {  
79 - $.each(names, function (i, name) {  
80 - message[name] = options[name];  
81 - });  
82 - message.dataType = message.dataType.replace('postmessage ', '');  
83 - $(window).bind(eventName, function (e) {  
84 - e = e.originalEvent;  
85 - var data = e.data,  
86 - ev;  
87 - if (e.origin === target && data.id === message.id) {  
88 - if (data.type === 'progress') {  
89 - ev = document.createEvent('Event');  
90 - ev.initEvent(data.type, false, true);  
91 - $.extend(ev, data);  
92 - xhrUpload.dispatchEvent(ev);  
93 - } else {  
94 - completeCallback(  
95 - data.status,  
96 - data.statusText,  
97 - {postmessage: data.result},  
98 - data.headers  
99 - );  
100 - iframe.remove();  
101 - $(window).unbind(eventName);  
102 - }  
103 - }  
104 - });  
105 - iframe[0].contentWindow.postMessage(  
106 - message,  
107 - target  
108 - );  
109 - }).appendTo(document.body);  
110 - },  
111 - abort: function () {  
112 - if (iframe) {  
113 - iframe.remove();  
114 - }  
115 - }  
116 - };  
117 - }  
118 - });  
119 -  
120 -}));  
artbox-file/assets/js/cors/jquery.xdr-transport.js deleted
1 -/*  
2 - * jQuery XDomainRequest Transport Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2011, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - *  
11 - * Based on Julian Aubourg's ajaxHooks xdr.js:  
12 - * https://github.com/jaubourg/ajaxHooks/  
13 - */  
14 -  
15 -/* global define, require, window, XDomainRequest */  
16 -  
17 -(function (factory) {  
18 - 'use strict';  
19 - if (typeof define === 'function' && define.amd) {  
20 - // Register as an anonymous AMD module:  
21 - define(['jquery'], factory);  
22 - } else if (typeof exports === 'object') {  
23 - // Node/CommonJS:  
24 - factory(require('jquery'));  
25 - } else {  
26 - // Browser globals:  
27 - factory(window.jQuery);  
28 - }  
29 -}(function ($) {  
30 - 'use strict';  
31 - if (window.XDomainRequest && !$.support.cors) {  
32 - $.ajaxTransport(function (s) {  
33 - if (s.crossDomain && s.async) {  
34 - if (s.timeout) {  
35 - s.xdrTimeout = s.timeout;  
36 - delete s.timeout;  
37 - }  
38 - var xdr;  
39 - return {  
40 - send: function (headers, completeCallback) {  
41 - var addParamChar = /\?/.test(s.url) ? '&' : '?';  
42 - function callback(status, statusText, responses, responseHeaders) {  
43 - xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;  
44 - xdr = null;  
45 - completeCallback(status, statusText, responses, responseHeaders);  
46 - }  
47 - xdr = new XDomainRequest();  
48 - // XDomainRequest only supports GET and POST:  
49 - if (s.type === 'DELETE') {  
50 - s.url = s.url + addParamChar + '_method=DELETE';  
51 - s.type = 'POST';  
52 - } else if (s.type === 'PUT') {  
53 - s.url = s.url + addParamChar + '_method=PUT';  
54 - s.type = 'POST';  
55 - } else if (s.type === 'PATCH') {  
56 - s.url = s.url + addParamChar + '_method=PATCH';  
57 - s.type = 'POST';  
58 - }  
59 - xdr.open(s.type, s.url);  
60 - xdr.onload = function () {  
61 - callback(  
62 - 200,  
63 - 'OK',  
64 - {text: xdr.responseText},  
65 - 'Content-Type: ' + xdr.contentType  
66 - );  
67 - };  
68 - xdr.onerror = function () {  
69 - callback(404, 'Not Found');  
70 - };  
71 - if (s.xdrTimeout) {  
72 - xdr.ontimeout = function () {  
73 - callback(0, 'timeout');  
74 - };  
75 - xdr.timeout = s.xdrTimeout;  
76 - }  
77 - xdr.send((s.hasContent && s.data) || null);  
78 - },  
79 - abort: function () {  
80 - if (xdr) {  
81 - xdr.onerror = $.noop();  
82 - xdr.abort();  
83 - }  
84 - }  
85 - };  
86 - }  
87 - });  
88 - }  
89 -}));  
artbox-file/assets/js/jquery.fileupload-angular.js deleted
1 -/*  
2 - * jQuery File Upload AngularJS Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2013, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* jshint nomen:false */  
13 -/* global define, angular */  
14 -  
15 -(function (factory) {  
16 - 'use strict';  
17 - if (typeof define === 'function' && define.amd) {  
18 - // Register as an anonymous AMD module:  
19 - define([  
20 - 'jquery',  
21 - 'angular',  
22 - './jquery.fileupload-image',  
23 - './jquery.fileupload-audio',  
24 - './jquery.fileupload-video',  
25 - './jquery.fileupload-validate'  
26 - ], factory);  
27 - } else {  
28 - factory();  
29 - }  
30 -}(function () {  
31 - 'use strict';  
32 -  
33 - angular.module('blueimp.fileupload', [])  
34 -  
35 - // The fileUpload service provides configuration options  
36 - // for the fileUpload directive and default handlers for  
37 - // File Upload events:  
38 - .provider('fileUpload', function () {  
39 - var scopeEvalAsync = function (expression) {  
40 - var scope = angular.element(this)  
41 - .fileupload('option', 'scope');  
42 - // Schedule a new $digest cycle if not already inside of one  
43 - // and evaluate the given expression:  
44 - scope.$evalAsync(expression);  
45 - },  
46 - addFileMethods = function (scope, data) {  
47 - var files = data.files,  
48 - file = files[0];  
49 - angular.forEach(files, function (file, index) {  
50 - file._index = index;  
51 - file.$state = function () {  
52 - return data.state();  
53 - };  
54 - file.$processing = function () {  
55 - return data.processing();  
56 - };  
57 - file.$progress = function () {  
58 - return data.progress();  
59 - };  
60 - file.$response = function () {  
61 - return data.response();  
62 - };  
63 - });  
64 - file.$submit = function () {  
65 - if (!file.error) {  
66 - return data.submit();  
67 - }  
68 - };  
69 - file.$cancel = function () {  
70 - return data.abort();  
71 - };  
72 - },  
73 - $config;  
74 - $config = this.defaults = {  
75 - handleResponse: function (e, data) {  
76 - var files = data.result && data.result.files;  
77 - if (files) {  
78 - data.scope.replace(data.files, files);  
79 - } else if (data.errorThrown ||  
80 - data.textStatus === 'error') {  
81 - data.files[0].error = data.errorThrown ||  
82 - data.textStatus;  
83 - }  
84 - },  
85 - add: function (e, data) {  
86 - if (e.isDefaultPrevented()) {  
87 - return false;  
88 - }  
89 - var scope = data.scope,  
90 - filesCopy = [];  
91 - angular.forEach(data.files, function (file) {  
92 - filesCopy.push(file);  
93 - });  
94 - scope.$parent.$applyAsync(function () {  
95 - addFileMethods(scope, data);  
96 - var method = scope.option('prependFiles') ?  
97 - 'unshift' : 'push';  
98 - Array.prototype[method].apply(scope.queue, data.files);  
99 - });  
100 - data.process(function () {  
101 - return scope.process(data);  
102 - }).always(function () {  
103 - scope.$parent.$applyAsync(function () {  
104 - addFileMethods(scope, data);  
105 - scope.replace(filesCopy, data.files);  
106 - });  
107 - }).then(function () {  
108 - if ((scope.option('autoUpload') ||  
109 - data.autoUpload) &&  
110 - data.autoUpload !== false) {  
111 - data.submit();  
112 - }  
113 - });  
114 - },  
115 - done: function (e, data) {  
116 - if (e.isDefaultPrevented()) {  
117 - return false;  
118 - }  
119 - var that = this;  
120 - data.scope.$apply(function () {  
121 - data.handleResponse.call(that, e, data);  
122 - });  
123 - },  
124 - fail: function (e, data) {  
125 - if (e.isDefaultPrevented()) {  
126 - return false;  
127 - }  
128 - var that = this,  
129 - scope = data.scope;  
130 - if (data.errorThrown === 'abort') {  
131 - scope.clear(data.files);  
132 - return;  
133 - }  
134 - scope.$apply(function () {  
135 - data.handleResponse.call(that, e, data);  
136 - });  
137 - },  
138 - stop: scopeEvalAsync,  
139 - processstart: scopeEvalAsync,  
140 - processstop: scopeEvalAsync,  
141 - getNumberOfFiles: function () {  
142 - var scope = this.scope;  
143 - return scope.queue.length - scope.processing();  
144 - },  
145 - dataType: 'json',  
146 - autoUpload: false  
147 - };  
148 - this.$get = [  
149 - function () {  
150 - return {  
151 - defaults: $config  
152 - };  
153 - }  
154 - ];  
155 - })  
156 -  
157 - // Format byte numbers to readable presentations:  
158 - .provider('formatFileSizeFilter', function () {  
159 - var $config = {  
160 - // Byte units following the IEC format  
161 - // http://en.wikipedia.org/wiki/Kilobyte  
162 - units: [  
163 - {size: 1000000000, suffix: ' GB'},  
164 - {size: 1000000, suffix: ' MB'},  
165 - {size: 1000, suffix: ' KB'}  
166 - ]  
167 - };  
168 - this.defaults = $config;  
169 - this.$get = function () {  
170 - return function (bytes) {  
171 - if (!angular.isNumber(bytes)) {  
172 - return '';  
173 - }  
174 - var unit = true,  
175 - i = 0,  
176 - prefix,  
177 - suffix;  
178 - while (unit) {  
179 - unit = $config.units[i];  
180 - prefix = unit.prefix || '';  
181 - suffix = unit.suffix || '';  
182 - if (i === $config.units.length - 1 || bytes >= unit.size) {  
183 - return prefix + (bytes / unit.size).toFixed(2) + suffix;  
184 - }  
185 - i += 1;  
186 - }  
187 - };  
188 - };  
189 - })  
190 -  
191 - // The FileUploadController initializes the fileupload widget and  
192 - // provides scope methods to control the File Upload functionality:  
193 - .controller('FileUploadController', [  
194 - '$scope', '$element', '$attrs', '$window', 'fileUpload',  
195 - function ($scope, $element, $attrs, $window, fileUpload) {  
196 - var uploadMethods = {  
197 - progress: function () {  
198 - return $element.fileupload('progress');  
199 - },  
200 - active: function () {  
201 - return $element.fileupload('active');  
202 - },  
203 - option: function (option, data) {  
204 - if (arguments.length === 1) {  
205 - return $element.fileupload('option', option);  
206 - }  
207 - $element.fileupload('option', option, data);  
208 - },  
209 - add: function (data) {  
210 - return $element.fileupload('add', data);  
211 - },  
212 - send: function (data) {  
213 - return $element.fileupload('send', data);  
214 - },  
215 - process: function (data) {  
216 - return $element.fileupload('process', data);  
217 - },  
218 - processing: function (data) {  
219 - return $element.fileupload('processing', data);  
220 - }  
221 - };  
222 - $scope.disabled = !$window.jQuery.support.fileInput;  
223 - $scope.queue = $scope.queue || [];  
224 - $scope.clear = function (files) {  
225 - var queue = this.queue,  
226 - i = queue.length,  
227 - file = files,  
228 - length = 1;  
229 - if (angular.isArray(files)) {  
230 - file = files[0];  
231 - length = files.length;  
232 - }  
233 - while (i) {  
234 - i -= 1;  
235 - if (queue[i] === file) {  
236 - return queue.splice(i, length);  
237 - }  
238 - }  
239 - };  
240 - $scope.replace = function (oldFiles, newFiles) {  
241 - var queue = this.queue,  
242 - file = oldFiles[0],  
243 - i,  
244 - j;  
245 - for (i = 0; i < queue.length; i += 1) {  
246 - if (queue[i] === file) {  
247 - for (j = 0; j < newFiles.length; j += 1) {  
248 - queue[i + j] = newFiles[j];  
249 - }  
250 - return;  
251 - }  
252 - }  
253 - };  
254 - $scope.applyOnQueue = function (method) {  
255 - var list = this.queue.slice(0),  
256 - i,  
257 - file;  
258 - for (i = 0; i < list.length; i += 1) {  
259 - file = list[i];  
260 - if (file[method]) {  
261 - file[method]();  
262 - }  
263 - }  
264 - };  
265 - $scope.submit = function () {  
266 - this.applyOnQueue('$submit');  
267 - };  
268 - $scope.cancel = function () {  
269 - this.applyOnQueue('$cancel');  
270 - };  
271 - // Add upload methods to the scope:  
272 - angular.extend($scope, uploadMethods);  
273 - // The fileupload widget will initialize with  
274 - // the options provided via "data-"-parameters,  
275 - // as well as those given via options object:  
276 - $element.fileupload(angular.extend(  
277 - {scope: $scope},  
278 - fileUpload.defaults  
279 - )).on('fileuploadadd', function (e, data) {  
280 - data.scope = $scope;  
281 - }).on('fileuploadfail', function (e, data) {  
282 - if (data.errorThrown === 'abort') {  
283 - return;  
284 - }  
285 - if (data.dataType &&  
286 - data.dataType.indexOf('json') === data.dataType.length - 4) {  
287 - try {  
288 - data.result = angular.fromJson(data.jqXHR.responseText);  
289 - } catch (ignore) {}  
290 - }  
291 - }).on([  
292 - 'fileuploadadd',  
293 - 'fileuploadsubmit',  
294 - 'fileuploadsend',  
295 - 'fileuploaddone',  
296 - 'fileuploadfail',  
297 - 'fileuploadalways',  
298 - 'fileuploadprogress',  
299 - 'fileuploadprogressall',  
300 - 'fileuploadstart',  
301 - 'fileuploadstop',  
302 - 'fileuploadchange',  
303 - 'fileuploadpaste',  
304 - 'fileuploaddrop',  
305 - 'fileuploaddragover',  
306 - 'fileuploadchunksend',  
307 - 'fileuploadchunkdone',  
308 - 'fileuploadchunkfail',  
309 - 'fileuploadchunkalways',  
310 - 'fileuploadprocessstart',  
311 - 'fileuploadprocess',  
312 - 'fileuploadprocessdone',  
313 - 'fileuploadprocessfail',  
314 - 'fileuploadprocessalways',  
315 - 'fileuploadprocessstop'  
316 - ].join(' '), function (e, data) {  
317 - $scope.$parent.$applyAsync(function () {  
318 - if ($scope.$emit(e.type, data).defaultPrevented) {  
319 - e.preventDefault();  
320 - }  
321 - });  
322 - }).on('remove', function () {  
323 - // Remove upload methods from the scope,  
324 - // when the widget is removed:  
325 - var method;  
326 - for (method in uploadMethods) {  
327 - if (uploadMethods.hasOwnProperty(method)) {  
328 - delete $scope[method];  
329 - }  
330 - }  
331 - });  
332 - // Observe option changes:  
333 - $scope.$watch(  
334 - $attrs.fileUpload,  
335 - function (newOptions) {  
336 - if (newOptions) {  
337 - $element.fileupload('option', newOptions);  
338 - }  
339 - }  
340 - );  
341 - }  
342 - ])  
343 -  
344 - // Provide File Upload progress feedback:  
345 - .controller('FileUploadProgressController', [  
346 - '$scope', '$attrs', '$parse',  
347 - function ($scope, $attrs, $parse) {  
348 - var fn = $parse($attrs.fileUploadProgress),  
349 - update = function () {  
350 - var progress = fn($scope);  
351 - if (!progress || !progress.total) {  
352 - return;  
353 - }  
354 - $scope.num = Math.floor(  
355 - progress.loaded / progress.total * 100  
356 - );  
357 - };  
358 - update();  
359 - $scope.$watch(  
360 - $attrs.fileUploadProgress + '.loaded',  
361 - function (newValue, oldValue) {  
362 - if (newValue !== oldValue) {  
363 - update();  
364 - }  
365 - }  
366 - );  
367 - }  
368 - ])  
369 -  
370 - // Display File Upload previews:  
371 - .controller('FileUploadPreviewController', [  
372 - '$scope', '$element', '$attrs',  
373 - function ($scope, $element, $attrs) {  
374 - $scope.$watch(  
375 - $attrs.fileUploadPreview + '.preview',  
376 - function (preview) {  
377 - $element.empty();  
378 - if (preview) {  
379 - $element.append(preview);  
380 - }  
381 - }  
382 - );  
383 - }  
384 - ])  
385 -  
386 - .directive('fileUpload', function () {  
387 - return {  
388 - controller: 'FileUploadController',  
389 - scope: true  
390 - };  
391 - })  
392 -  
393 - .directive('fileUploadProgress', function () {  
394 - return {  
395 - controller: 'FileUploadProgressController',  
396 - scope: true  
397 - };  
398 - })  
399 -  
400 - .directive('fileUploadPreview', function () {  
401 - return {  
402 - controller: 'FileUploadPreviewController'  
403 - };  
404 - })  
405 -  
406 - // Enhance the HTML5 download attribute to  
407 - // allow drag&drop of files to the desktop:  
408 - .directive('download', function () {  
409 - return function (scope, elm) {  
410 - elm.on('dragstart', function (e) {  
411 - try {  
412 - e.originalEvent.dataTransfer.setData(  
413 - 'DownloadURL',  
414 - [  
415 - 'application/octet-stream',  
416 - elm.prop('download'),  
417 - elm.prop('href')  
418 - ].join(':')  
419 - );  
420 - } catch (ignore) {}  
421 - });  
422 - };  
423 - });  
424 -  
425 -}));  
artbox-file/assets/js/jquery.fileupload-audio.js deleted
1 -/*  
2 - * jQuery File Upload Audio Preview Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2013, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* jshint nomen:false */  
13 -/* global define, require, window, document */  
14 -  
15 -(function (factory) {  
16 - 'use strict';  
17 - if (typeof define === 'function' && define.amd) {  
18 - // Register as an anonymous AMD module:  
19 - define([  
20 - 'jquery',  
21 - 'load-image',  
22 - './jquery.fileupload-process'  
23 - ], factory);  
24 - } else if (typeof exports === 'object') {  
25 - // Node/CommonJS:  
26 - factory(  
27 - require('jquery'),  
28 - require('load-image')  
29 - );  
30 - } else {  
31 - // Browser globals:  
32 - factory(  
33 - window.jQuery,  
34 - window.loadImage  
35 - );  
36 - }  
37 -}(function ($, loadImage) {  
38 - 'use strict';  
39 -  
40 - // Prepend to the default processQueue:  
41 - $.blueimp.fileupload.prototype.options.processQueue.unshift(  
42 - {  
43 - action: 'loadAudio',  
44 - // Use the action as prefix for the "@" options:  
45 - prefix: true,  
46 - fileTypes: '@',  
47 - maxFileSize: '@',  
48 - disabled: '@disableAudioPreview'  
49 - },  
50 - {  
51 - action: 'setAudio',  
52 - name: '@audioPreviewName',  
53 - disabled: '@disableAudioPreview'  
54 - }  
55 - );  
56 -  
57 - // The File Upload Audio Preview plugin extends the fileupload widget  
58 - // with audio preview functionality:  
59 - $.widget('blueimp.fileupload', $.blueimp.fileupload, {  
60 -  
61 - options: {  
62 - // The regular expression for the types of audio files to load,  
63 - // matched against the file type:  
64 - loadAudioFileTypes: /^audio\/.*$/  
65 - },  
66 -  
67 - _audioElement: document.createElement('audio'),  
68 -  
69 - processActions: {  
70 -  
71 - // Loads the audio file given via data.files and data.index  
72 - // as audio element if the browser supports playing it.  
73 - // Accepts the options fileTypes (regular expression)  
74 - // and maxFileSize (integer) to limit the files to load:  
75 - loadAudio: function (data, options) {  
76 - if (options.disabled) {  
77 - return data;  
78 - }  
79 - var file = data.files[data.index],  
80 - url,  
81 - audio;  
82 - if (this._audioElement.canPlayType &&  
83 - this._audioElement.canPlayType(file.type) &&  
84 - ($.type(options.maxFileSize) !== 'number' ||  
85 - file.size <= options.maxFileSize) &&  
86 - (!options.fileTypes ||  
87 - options.fileTypes.test(file.type))) {  
88 - url = loadImage.createObjectURL(file);  
89 - if (url) {  
90 - audio = this._audioElement.cloneNode(false);  
91 - audio.src = url;  
92 - audio.controls = true;  
93 - data.audio = audio;  
94 - return data;  
95 - }  
96 - }  
97 - return data;  
98 - },  
99 -  
100 - // Sets the audio element as a property of the file object:  
101 - setAudio: function (data, options) {  
102 - if (data.audio && !options.disabled) {  
103 - data.files[data.index][options.name || 'preview'] = data.audio;  
104 - }  
105 - return data;  
106 - }  
107 -  
108 - }  
109 -  
110 - });  
111 -  
112 -}));  
artbox-file/assets/js/jquery.fileupload-image.js deleted
1 -/*  
2 - * jQuery File Upload Image Preview & Resize Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2013, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* jshint nomen:false */  
13 -/* global define, require, window, Blob */  
14 -  
15 -(function (factory) {  
16 - 'use strict';  
17 - if (typeof define === 'function' && define.amd) {  
18 - // Register as an anonymous AMD module:  
19 - define([  
20 - 'jquery',  
21 - 'load-image',  
22 - 'load-image-meta',  
23 - 'load-image-exif',  
24 - 'load-image-ios',  
25 - 'canvas-to-blob',  
26 - './jquery.fileupload-process'  
27 - ], factory);  
28 - } else if (typeof exports === 'object') {  
29 - // Node/CommonJS:  
30 - factory(  
31 - require('jquery'),  
32 - require('load-image')  
33 - );  
34 - } else {  
35 - // Browser globals:  
36 - factory(  
37 - window.jQuery,  
38 - window.loadImage  
39 - );  
40 - }  
41 -}(function ($, loadImage) {  
42 - 'use strict';  
43 -  
44 - // Prepend to the default processQueue:  
45 - $.blueimp.fileupload.prototype.options.processQueue.unshift(  
46 - {  
47 - action: 'loadImageMetaData',  
48 - disableImageHead: '@',  
49 - disableExif: '@',  
50 - disableExifThumbnail: '@',  
51 - disableExifSub: '@',  
52 - disableExifGps: '@',  
53 - disabled: '@disableImageMetaDataLoad'  
54 - },  
55 - {  
56 - action: 'loadImage',  
57 - // Use the action as prefix for the "@" options:  
58 - prefix: true,  
59 - fileTypes: '@',  
60 - maxFileSize: '@',  
61 - noRevoke: '@',  
62 - disabled: '@disableImageLoad'  
63 - },  
64 - {  
65 - action: 'resizeImage',  
66 - // Use "image" as prefix for the "@" options:  
67 - prefix: 'image',  
68 - maxWidth: '@',  
69 - maxHeight: '@',  
70 - minWidth: '@',  
71 - minHeight: '@',  
72 - crop: '@',  
73 - orientation: '@',  
74 - forceResize: '@',  
75 - disabled: '@disableImageResize'  
76 - },  
77 - {  
78 - action: 'saveImage',  
79 - quality: '@imageQuality',  
80 - type: '@imageType',  
81 - disabled: '@disableImageResize'  
82 - },  
83 - {  
84 - action: 'saveImageMetaData',  
85 - disabled: '@disableImageMetaDataSave'  
86 - },  
87 - {  
88 - action: 'resizeImage',  
89 - // Use "preview" as prefix for the "@" options:  
90 - prefix: 'preview',  
91 - maxWidth: '@',  
92 - maxHeight: '@',  
93 - minWidth: '@',  
94 - minHeight: '@',  
95 - crop: '@',  
96 - orientation: '@',  
97 - thumbnail: '@',  
98 - canvas: '@',  
99 - disabled: '@disableImagePreview'  
100 - },  
101 - {  
102 - action: 'setImage',  
103 - name: '@imagePreviewName',  
104 - disabled: '@disableImagePreview'  
105 - },  
106 - {  
107 - action: 'deleteImageReferences',  
108 - disabled: '@disableImageReferencesDeletion'  
109 - }  
110 - );  
111 -  
112 - // The File Upload Resize plugin extends the fileupload widget  
113 - // with image resize functionality:  
114 - $.widget('blueimp.fileupload', $.blueimp.fileupload, {  
115 -  
116 - options: {  
117 - // The regular expression for the types of images to load:  
118 - // matched against the file type:  
119 - loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/,  
120 - // The maximum file size of images to load:  
121 - loadImageMaxFileSize: 10000000, // 10MB  
122 - // The maximum width of resized images:  
123 - imageMaxWidth: 1920,  
124 - // The maximum height of resized images:  
125 - imageMaxHeight: 1080,  
126 - // Defines the image orientation (1-8) or takes the orientation  
127 - // value from Exif data if set to true:  
128 - imageOrientation: false,  
129 - // Define if resized images should be cropped or only scaled:  
130 - imageCrop: false,  
131 - // Disable the resize image functionality by default:  
132 - disableImageResize: true,  
133 - // The maximum width of the preview images:  
134 - previewMaxWidth: 80,  
135 - // The maximum height of the preview images:  
136 - previewMaxHeight: 80,  
137 - // Defines the preview orientation (1-8) or takes the orientation  
138 - // value from Exif data if set to true:  
139 - previewOrientation: true,  
140 - // Create the preview using the Exif data thumbnail:  
141 - previewThumbnail: true,  
142 - // Define if preview images should be cropped or only scaled:  
143 - previewCrop: false,  
144 - // Define if preview images should be resized as canvas elements:  
145 - previewCanvas: true  
146 - },  
147 -  
148 - processActions: {  
149 -  
150 - // Loads the image given via data.files and data.index  
151 - // as img element, if the browser supports the File API.  
152 - // Accepts the options fileTypes (regular expression)  
153 - // and maxFileSize (integer) to limit the files to load:  
154 - loadImage: function (data, options) {  
155 - if (options.disabled) {  
156 - return data;  
157 - }  
158 - var that = this,  
159 - file = data.files[data.index],  
160 - dfd = $.Deferred();  
161 - if (($.type(options.maxFileSize) === 'number' &&  
162 - file.size > options.maxFileSize) ||  
163 - (options.fileTypes &&  
164 - !options.fileTypes.test(file.type)) ||  
165 - !loadImage(  
166 - file,  
167 - function (img) {  
168 - if (img.src) {  
169 - data.img = img;  
170 - }  
171 - dfd.resolveWith(that, [data]);  
172 - },  
173 - options  
174 - )) {  
175 - return data;  
176 - }  
177 - return dfd.promise();  
178 - },  
179 -  
180 - // Resizes the image given as data.canvas or data.img  
181 - // and updates data.canvas or data.img with the resized image.  
182 - // Also stores the resized image as preview property.  
183 - // Accepts the options maxWidth, maxHeight, minWidth,  
184 - // minHeight, canvas and crop:  
185 - resizeImage: function (data, options) {  
186 - if (options.disabled || !(data.canvas || data.img)) {  
187 - return data;  
188 - }  
189 - options = $.extend({canvas: true}, options);  
190 - var that = this,  
191 - dfd = $.Deferred(),  
192 - img = (options.canvas && data.canvas) || data.img,  
193 - resolve = function (newImg) {  
194 - if (newImg && (newImg.width !== img.width ||  
195 - newImg.height !== img.height ||  
196 - options.forceResize)) {  
197 - data[newImg.getContext ? 'canvas' : 'img'] = newImg;  
198 - }  
199 - data.preview = newImg;  
200 - dfd.resolveWith(that, [data]);  
201 - },  
202 - thumbnail;  
203 - if (data.exif) {  
204 - if (options.orientation === true) {  
205 - options.orientation = data.exif.get('Orientation');  
206 - }  
207 - if (options.thumbnail) {  
208 - thumbnail = data.exif.get('Thumbnail');  
209 - if (thumbnail) {  
210 - loadImage(thumbnail, resolve, options);  
211 - return dfd.promise();  
212 - }  
213 - }  
214 - // Prevent orienting the same image twice:  
215 - if (data.orientation) {  
216 - delete options.orientation;  
217 - } else {  
218 - data.orientation = options.orientation;  
219 - }  
220 - }  
221 - if (img) {  
222 - resolve(loadImage.scale(img, options));  
223 - return dfd.promise();  
224 - }  
225 - return data;  
226 - },  
227 -  
228 - // Saves the processed image given as data.canvas  
229 - // inplace at data.index of data.files:  
230 - saveImage: function (data, options) {  
231 - if (!data.canvas || options.disabled) {  
232 - return data;  
233 - }  
234 - var that = this,  
235 - file = data.files[data.index],  
236 - dfd = $.Deferred();  
237 - if (data.canvas.toBlob) {  
238 - data.canvas.toBlob(  
239 - function (blob) {  
240 - if (!blob.name) {  
241 - if (file.type === blob.type) {  
242 - blob.name = file.name;  
243 - } else if (file.name) {  
244 - blob.name = file.name.replace(  
245 - /\.\w+$/,  
246 - '.' + blob.type.substr(6)  
247 - );  
248 - }  
249 - }  
250 - // Don't restore invalid meta data:  
251 - if (file.type !== blob.type) {  
252 - delete data.imageHead;  
253 - }  
254 - // Store the created blob at the position  
255 - // of the original file in the files list:  
256 - data.files[data.index] = blob;  
257 - dfd.resolveWith(that, [data]);  
258 - },  
259 - options.type || file.type,  
260 - options.quality  
261 - );  
262 - } else {  
263 - return data;  
264 - }  
265 - return dfd.promise();  
266 - },  
267 -  
268 - loadImageMetaData: function (data, options) {  
269 - if (options.disabled) {  
270 - return data;  
271 - }  
272 - var that = this,  
273 - dfd = $.Deferred();  
274 - loadImage.parseMetaData(data.files[data.index], function (result) {  
275 - $.extend(data, result);  
276 - dfd.resolveWith(that, [data]);  
277 - }, options);  
278 - return dfd.promise();  
279 - },  
280 -  
281 - saveImageMetaData: function (data, options) {  
282 - if (!(data.imageHead && data.canvas &&  
283 - data.canvas.toBlob && !options.disabled)) {  
284 - return data;  
285 - }  
286 - var file = data.files[data.index],  
287 - blob = new Blob([  
288 - data.imageHead,  
289 - // Resized images always have a head size of 20 bytes,  
290 - // including the JPEG marker and a minimal JFIF header:  
291 - this._blobSlice.call(file, 20)  
292 - ], {type: file.type});  
293 - blob.name = file.name;  
294 - data.files[data.index] = blob;  
295 - return data;  
296 - },  
297 -  
298 - // Sets the resized version of the image as a property of the  
299 - // file object, must be called after "saveImage":  
300 - setImage: function (data, options) {  
301 - if (data.preview && !options.disabled) {  
302 - data.files[data.index][options.name || 'preview'] = data.preview;  
303 - }  
304 - return data;  
305 - },  
306 -  
307 - deleteImageReferences: function (data, options) {  
308 - if (!options.disabled) {  
309 - delete data.img;  
310 - delete data.canvas;  
311 - delete data.preview;  
312 - delete data.imageHead;  
313 - }  
314 - return data;  
315 - }  
316 -  
317 - }  
318 -  
319 - });  
320 -  
321 -}));  
artbox-file/assets/js/jquery.fileupload-jquery-ui.js deleted
1 -/*  
2 - * jQuery File Upload jQuery UI Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2013, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* jshint nomen:false */  
13 -/* global define, require, window */  
14 -  
15 -(function (factory) {  
16 - 'use strict';  
17 - if (typeof define === 'function' && define.amd) {  
18 - // Register as an anonymous AMD module:  
19 - define(['jquery', './jquery.fileupload-ui'], factory);  
20 - } else if (typeof exports === 'object') {  
21 - // Node/CommonJS:  
22 - factory(require('jquery'));  
23 - } else {  
24 - // Browser globals:  
25 - factory(window.jQuery);  
26 - }  
27 -}(function ($) {  
28 - 'use strict';  
29 -  
30 - $.widget('blueimp.fileupload', $.blueimp.fileupload, {  
31 -  
32 - options: {  
33 - processdone: function (e, data) {  
34 - data.context.find('.start').button('enable');  
35 - },  
36 - progress: function (e, data) {  
37 - if (data.context) {  
38 - data.context.find('.progress').progressbar(  
39 - 'option',  
40 - 'value',  
41 - parseInt(data.loaded / data.total * 100, 10)  
42 - );  
43 - }  
44 - },  
45 - progressall: function (e, data) {  
46 - var $this = $(this);  
47 - $this.find('.fileupload-progress')  
48 - .find('.progress').progressbar(  
49 - 'option',  
50 - 'value',  
51 - parseInt(data.loaded / data.total * 100, 10)  
52 - ).end()  
53 - .find('.progress-extended').each(function () {  
54 - $(this).html(  
55 - ($this.data('blueimp-fileupload') ||  
56 - $this.data('fileupload'))  
57 - ._renderExtendedProgress(data)  
58 - );  
59 - });  
60 - }  
61 - },  
62 -  
63 - _renderUpload: function (func, files) {  
64 - var node = this._super(func, files),  
65 - showIconText = $(window).width() > 480;  
66 - node.find('.progress').empty().progressbar();  
67 - node.find('.start').button({  
68 - icons: {primary: 'ui-icon-circle-arrow-e'},  
69 - text: showIconText  
70 - });  
71 - node.find('.cancel').button({  
72 - icons: {primary: 'ui-icon-cancel'},  
73 - text: showIconText  
74 - });  
75 - if (node.hasClass('fade')) {  
76 - node.hide();  
77 - }  
78 - return node;  
79 - },  
80 -  
81 - _renderDownload: function (func, files) {  
82 - var node = this._super(func, files),  
83 - showIconText = $(window).width() > 480;  
84 - node.find('.delete').button({  
85 - icons: {primary: 'ui-icon-trash'},  
86 - text: showIconText  
87 - });  
88 - if (node.hasClass('fade')) {  
89 - node.hide();  
90 - }  
91 - return node;  
92 - },  
93 -  
94 - _startHandler: function (e) {  
95 - $(e.currentTarget).button('disable');  
96 - this._super(e);  
97 - },  
98 -  
99 - _transition: function (node) {  
100 - var deferred = $.Deferred();  
101 - if (node.hasClass('fade')) {  
102 - node.fadeToggle(  
103 - this.options.transitionDuration,  
104 - this.options.transitionEasing,  
105 - function () {  
106 - deferred.resolveWith(node);  
107 - }  
108 - );  
109 - } else {  
110 - deferred.resolveWith(node);  
111 - }  
112 - return deferred;  
113 - },  
114 -  
115 - _create: function () {  
116 - this._super();  
117 - this.element  
118 - .find('.fileupload-buttonbar')  
119 - .find('.fileinput-button').each(function () {  
120 - var input = $(this).find('input:file').detach();  
121 - $(this)  
122 - .button({icons: {primary: 'ui-icon-plusthick'}})  
123 - .append(input);  
124 - })  
125 - .end().find('.start')  
126 - .button({icons: {primary: 'ui-icon-circle-arrow-e'}})  
127 - .end().find('.cancel')  
128 - .button({icons: {primary: 'ui-icon-cancel'}})  
129 - .end().find('.delete')  
130 - .button({icons: {primary: 'ui-icon-trash'}})  
131 - .end().find('.progress').progressbar();  
132 - },  
133 -  
134 - _destroy: function () {  
135 - this.element  
136 - .find('.fileupload-buttonbar')  
137 - .find('.fileinput-button').each(function () {  
138 - var input = $(this).find('input:file').detach();  
139 - $(this)  
140 - .button('destroy')  
141 - .append(input);  
142 - })  
143 - .end().find('.start')  
144 - .button('destroy')  
145 - .end().find('.cancel')  
146 - .button('destroy')  
147 - .end().find('.delete')  
148 - .button('destroy')  
149 - .end().find('.progress').progressbar('destroy');  
150 - this._super();  
151 - }  
152 -  
153 - });  
154 -  
155 -}));  
artbox-file/assets/js/jquery.fileupload-process.js deleted
1 -/*  
2 - * jQuery File Upload Processing Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2012, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* jshint nomen:false */  
13 -/* global define, require, window */  
14 -  
15 -(function (factory) {  
16 - 'use strict';  
17 - if (typeof define === 'function' && define.amd) {  
18 - // Register as an anonymous AMD module:  
19 - define([  
20 - 'jquery',  
21 - './jquery.fileupload'  
22 - ], factory);  
23 - } else if (typeof exports === 'object') {  
24 - // Node/CommonJS:  
25 - factory(require('jquery'));  
26 - } else {  
27 - // Browser globals:  
28 - factory(  
29 - window.jQuery  
30 - );  
31 - }  
32 -}(function ($) {  
33 - 'use strict';  
34 -  
35 - var originalAdd = $.blueimp.fileupload.prototype.options.add;  
36 -  
37 - // The File Upload Processing plugin extends the fileupload widget  
38 - // with file processing functionality:  
39 - $.widget('blueimp.fileupload', $.blueimp.fileupload, {  
40 -  
41 - options: {  
42 - // The list of processing actions:  
43 - processQueue: [  
44 - /*  
45 - {  
46 - action: 'log',  
47 - type: 'debug'  
48 - }  
49 - */  
50 - ],  
51 - add: function (e, data) {  
52 - var $this = $(this);  
53 - data.process(function () {  
54 - return $this.fileupload('process', data);  
55 - });  
56 - originalAdd.call(this, e, data);  
57 - }  
58 - },  
59 -  
60 - processActions: {  
61 - /*  
62 - log: function (data, options) {  
63 - console[options.type](  
64 - 'Processing "' + data.files[data.index].name + '"'  
65 - );  
66 - }  
67 - */  
68 - },  
69 -  
70 - _processFile: function (data, originalData) {  
71 - var that = this,  
72 - dfd = $.Deferred().resolveWith(that, [data]),  
73 - chain = dfd.promise();  
74 - this._trigger('process', null, data);  
75 - $.each(data.processQueue, function (i, settings) {  
76 - var func = function (data) {  
77 - if (originalData.errorThrown) {  
78 - return $.Deferred()  
79 - .rejectWith(that, [originalData]).promise();  
80 - }  
81 - return that.processActions[settings.action].call(  
82 - that,  
83 - data,  
84 - settings  
85 - );  
86 - };  
87 - chain = chain.pipe(func, settings.always && func);  
88 - });  
89 - chain  
90 - .done(function () {  
91 - that._trigger('processdone', null, data);  
92 - that._trigger('processalways', null, data);  
93 - })  
94 - .fail(function () {  
95 - that._trigger('processfail', null, data);  
96 - that._trigger('processalways', null, data);  
97 - });  
98 - return chain;  
99 - },  
100 -  
101 - // Replaces the settings of each processQueue item that  
102 - // are strings starting with an "@", using the remaining  
103 - // substring as key for the option map,  
104 - // e.g. "@autoUpload" is replaced with options.autoUpload:  
105 - _transformProcessQueue: function (options) {  
106 - var processQueue = [];  
107 - $.each(options.processQueue, function () {  
108 - var settings = {},  
109 - action = this.action,  
110 - prefix = this.prefix === true ? action : this.prefix;  
111 - $.each(this, function (key, value) {  
112 - if ($.type(value) === 'string' &&  
113 - value.charAt(0) === '@') {  
114 - settings[key] = options[  
115 - value.slice(1) || (prefix ? prefix +  
116 - key.charAt(0).toUpperCase() + key.slice(1) : key)  
117 - ];  
118 - } else {  
119 - settings[key] = value;  
120 - }  
121 -  
122 - });  
123 - processQueue.push(settings);  
124 - });  
125 - options.processQueue = processQueue;  
126 - },  
127 -  
128 - // Returns the number of files currently in the processsing queue:  
129 - processing: function () {  
130 - return this._processing;  
131 - },  
132 -  
133 - // Processes the files given as files property of the data parameter,  
134 - // returns a Promise object that allows to bind callbacks:  
135 - process: function (data) {  
136 - var that = this,  
137 - options = $.extend({}, this.options, data);  
138 - if (options.processQueue && options.processQueue.length) {  
139 - this._transformProcessQueue(options);  
140 - if (this._processing === 0) {  
141 - this._trigger('processstart');  
142 - }  
143 - $.each(data.files, function (index) {  
144 - var opts = index ? $.extend({}, options) : options,  
145 - func = function () {  
146 - if (data.errorThrown) {  
147 - return $.Deferred()  
148 - .rejectWith(that, [data]).promise();  
149 - }  
150 - return that._processFile(opts, data);  
151 - };  
152 - opts.index = index;  
153 - that._processing += 1;  
154 - that._processingQueue = that._processingQueue.pipe(func, func)  
155 - .always(function () {  
156 - that._processing -= 1;  
157 - if (that._processing === 0) {  
158 - that._trigger('processstop');  
159 - }  
160 - });  
161 - });  
162 - }  
163 - return this._processingQueue;  
164 - },  
165 -  
166 - _create: function () {  
167 - this._super();  
168 - this._processing = 0;  
169 - this._processingQueue = $.Deferred().resolveWith(this)  
170 - .promise();  
171 - }  
172 -  
173 - });  
174 -  
175 -}));  
artbox-file/assets/js/jquery.fileupload-ui.js deleted
1 -/*  
2 - * jQuery File Upload User Interface Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2010, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* jshint nomen:false */  
13 -/* global define, require, window */  
14 -  
15 -(function (factory) {  
16 - 'use strict';  
17 - if (typeof define === 'function' && define.amd) {  
18 - // Register as an anonymous AMD module:  
19 - define([  
20 - 'jquery',  
21 - 'tmpl',  
22 - './jquery.fileupload-image',  
23 - './jquery.fileupload-audio',  
24 - './jquery.fileupload-video',  
25 - './jquery.fileupload-validate'  
26 - ], factory);  
27 - } else if (typeof exports === 'object') {  
28 - // Node/CommonJS:  
29 - factory(  
30 - require('jquery'),  
31 - require('tmpl')  
32 - );  
33 - } else {  
34 - // Browser globals:  
35 - factory(  
36 - window.jQuery,  
37 - window.tmpl  
38 - );  
39 - }  
40 -}(function ($, tmpl) {  
41 - 'use strict';  
42 -  
43 - $.blueimp.fileupload.prototype._specialOptions.push(  
44 - 'filesContainer',  
45 - 'uploadTemplateId',  
46 - 'downloadTemplateId'  
47 - );  
48 -  
49 - // The UI version extends the file upload widget  
50 - // and adds complete user interface interaction:  
51 - $.widget('blueimp.fileupload', $.blueimp.fileupload, {  
52 -  
53 - options: {  
54 - // By default, files added to the widget are uploaded as soon  
55 - // as the user clicks on the start buttons. To enable automatic  
56 - // uploads, set the following option to true:  
57 - autoUpload: false,  
58 - // The ID of the upload template:  
59 - uploadTemplateId: 'template-upload',  
60 - // The ID of the download template:  
61 - downloadTemplateId: 'template-download',  
62 - // The container for the list of files. If undefined, it is set to  
63 - // an element with class "files" inside of the widget element:  
64 - filesContainer: undefined,  
65 - // By default, files are appended to the files container.  
66 - // Set the following option to true, to prepend files instead:  
67 - prependFiles: false,  
68 - // The expected data type of the upload response, sets the dataType  
69 - // option of the $.ajax upload requests:  
70 - dataType: 'json',  
71 -  
72 - // Error and info messages:  
73 - messages: {  
74 - unknownError: 'Unknown error'  
75 - },  
76 -  
77 - // Function returning the current number of files,  
78 - // used by the maxNumberOfFiles validation:  
79 - getNumberOfFiles: function () {  
80 - return this.filesContainer.children()  
81 - .not('.processing').length;  
82 - },  
83 -  
84 - // Callback to retrieve the list of files from the server response:  
85 - getFilesFromResponse: function (data) {  
86 - if (data.result && $.isArray(data.result.files)) {  
87 - return data.result.files;  
88 - }  
89 - return [];  
90 - },  
91 -  
92 - // The add callback is invoked as soon as files are added to the fileupload  
93 - // widget (via file input selection, drag & drop or add API call).  
94 - // See the basic file upload widget for more information:  
95 - add: function (e, data) {  
96 - if (e.isDefaultPrevented()) {  
97 - return false;  
98 - }  
99 - var $this = $(this),  
100 - that = $this.data('blueimp-fileupload') ||  
101 - $this.data('fileupload'),  
102 - options = that.options;  
103 - data.context = that._renderUpload(data.files)  
104 - .data('data', data)  
105 - .addClass('processing');  
106 - options.filesContainer[  
107 - options.prependFiles ? 'prepend' : 'append'  
108 - ](data.context);  
109 - that._forceReflow(data.context);  
110 - that._transition(data.context);  
111 - data.process(function () {  
112 - return $this.fileupload('process', data);  
113 - }).always(function () {  
114 - data.context.each(function (index) {  
115 - $(this).find('.size').text(  
116 - that._formatFileSize(data.files[index].size)  
117 - );  
118 - }).removeClass('processing');  
119 - that._renderPreviews(data);  
120 - }).done(function () {  
121 - data.context.find('.start').prop('disabled', false);  
122 - if ((that._trigger('added', e, data) !== false) &&  
123 - (options.autoUpload || data.autoUpload) &&  
124 - data.autoUpload !== false) {  
125 - data.submit();  
126 - }  
127 - }).fail(function () {  
128 - if (data.files.error) {  
129 - data.context.each(function (index) {  
130 - var error = data.files[index].error;  
131 - if (error) {  
132 - $(this).find('.error').text(error);  
133 - }  
134 - });  
135 - }  
136 - });  
137 - },  
138 - // Callback for the start of each file upload request:  
139 - send: function (e, data) {  
140 - if (e.isDefaultPrevented()) {  
141 - return false;  
142 - }  
143 - var that = $(this).data('blueimp-fileupload') ||  
144 - $(this).data('fileupload');  
145 - if (data.context && data.dataType &&  
146 - data.dataType.substr(0, 6) === 'iframe') {  
147 - // Iframe Transport does not support progress events.  
148 - // In lack of an indeterminate progress bar, we set  
149 - // the progress to 100%, showing the full animated bar:  
150 - data.context  
151 - .find('.progress').addClass(  
152 - !$.support.transition && 'progress-animated'  
153 - )  
154 - .attr('aria-valuenow', 100)  
155 - .children().first().css(  
156 - 'width',  
157 - '100%'  
158 - );  
159 - }  
160 - return that._trigger('sent', e, data);  
161 - },  
162 - // Callback for successful uploads:  
163 - done: function (e, data) {  
164 - if (e.isDefaultPrevented()) {  
165 - return false;  
166 - }  
167 - var that = $(this).data('blueimp-fileupload') ||  
168 - $(this).data('fileupload'),  
169 - getFilesFromResponse = data.getFilesFromResponse ||  
170 - that.options.getFilesFromResponse,  
171 - files = getFilesFromResponse(data),  
172 - template,  
173 - deferred;  
174 - if (data.context) {  
175 - data.context.each(function (index) {  
176 - var file = files[index] ||  
177 - {error: 'Empty file upload result'};  
178 - deferred = that._addFinishedDeferreds();  
179 - that._transition($(this)).done(  
180 - function () {  
181 - var node = $(this);  
182 - template = that._renderDownload([file])  
183 - .replaceAll(node);  
184 - that._forceReflow(template);  
185 - that._transition(template).done(  
186 - function () {  
187 - data.context = $(this);  
188 - that._trigger('completed', e, data);  
189 - that._trigger('finished', e, data);  
190 - deferred.resolve();  
191 - }  
192 - );  
193 - }  
194 - );  
195 - });  
196 - } else {  
197 - template = that._renderDownload(files)[  
198 - that.options.prependFiles ? 'prependTo' : 'appendTo'  
199 - ](that.options.filesContainer);  
200 - that._forceReflow(template);  
201 - deferred = that._addFinishedDeferreds();  
202 - that._transition(template).done(  
203 - function () {  
204 - data.context = $(this);  
205 - that._trigger('completed', e, data);  
206 - that._trigger('finished', e, data);  
207 - deferred.resolve();  
208 - }  
209 - );  
210 - }  
211 - },  
212 - // Callback for failed (abort or error) uploads:  
213 - fail: function (e, data) {  
214 - if (e.isDefaultPrevented()) {  
215 - return false;  
216 - }  
217 - var that = $(this).data('blueimp-fileupload') ||  
218 - $(this).data('fileupload'),  
219 - template,  
220 - deferred;  
221 - if (data.context) {  
222 - data.context.each(function (index) {  
223 - if (data.errorThrown !== 'abort') {  
224 - var file = data.files[index];  
225 - file.error = file.error || data.errorThrown ||  
226 - data.i18n('unknownError');  
227 - deferred = that._addFinishedDeferreds();  
228 - that._transition($(this)).done(  
229 - function () {  
230 - var node = $(this);  
231 - template = that._renderDownload([file])  
232 - .replaceAll(node);  
233 - that._forceReflow(template);  
234 - that._transition(template).done(  
235 - function () {  
236 - data.context = $(this);  
237 - that._trigger('failed', e, data);  
238 - that._trigger('finished', e, data);  
239 - deferred.resolve();  
240 - }  
241 - );  
242 - }  
243 - );  
244 - } else {  
245 - deferred = that._addFinishedDeferreds();  
246 - that._transition($(this)).done(  
247 - function () {  
248 - $(this).remove();  
249 - that._trigger('failed', e, data);  
250 - that._trigger('finished', e, data);  
251 - deferred.resolve();  
252 - }  
253 - );  
254 - }  
255 - });  
256 - } else if (data.errorThrown !== 'abort') {  
257 - data.context = that._renderUpload(data.files)[  
258 - that.options.prependFiles ? 'prependTo' : 'appendTo'  
259 - ](that.options.filesContainer)  
260 - .data('data', data);  
261 - that._forceReflow(data.context);  
262 - deferred = that._addFinishedDeferreds();  
263 - that._transition(data.context).done(  
264 - function () {  
265 - data.context = $(this);  
266 - that._trigger('failed', e, data);  
267 - that._trigger('finished', e, data);  
268 - deferred.resolve();  
269 - }  
270 - );  
271 - } else {  
272 - that._trigger('failed', e, data);  
273 - that._trigger('finished', e, data);  
274 - that._addFinishedDeferreds().resolve();  
275 - }  
276 - },  
277 - // Callback for upload progress events:  
278 - progress: function (e, data) {  
279 - if (e.isDefaultPrevented()) {  
280 - return false;  
281 - }  
282 - var progress = Math.floor(data.loaded / data.total * 100);  
283 - if (data.context) {  
284 - data.context.each(function () {  
285 - $(this).find('.progress')  
286 - .attr('aria-valuenow', progress)  
287 - .children().first().css(  
288 - 'width',  
289 - progress + '%'  
290 - );  
291 - });  
292 - }  
293 - },  
294 - // Callback for global upload progress events:  
295 - progressall: function (e, data) {  
296 - if (e.isDefaultPrevented()) {  
297 - return false;  
298 - }  
299 - var $this = $(this),  
300 - progress = Math.floor(data.loaded / data.total * 100),  
301 - globalProgressNode = $this.find('.fileupload-progress'),  
302 - extendedProgressNode = globalProgressNode  
303 - .find('.progress-extended');  
304 - if (extendedProgressNode.length) {  
305 - extendedProgressNode.html(  
306 - ($this.data('blueimp-fileupload') || $this.data('fileupload'))  
307 - ._renderExtendedProgress(data)  
308 - );  
309 - }  
310 - globalProgressNode  
311 - .find('.progress')  
312 - .attr('aria-valuenow', progress)  
313 - .children().first().css(  
314 - 'width',  
315 - progress + '%'  
316 - );  
317 - },  
318 - // Callback for uploads start, equivalent to the global ajaxStart event:  
319 - start: function (e) {  
320 - if (e.isDefaultPrevented()) {  
321 - return false;  
322 - }  
323 - var that = $(this).data('blueimp-fileupload') ||  
324 - $(this).data('fileupload');  
325 - that._resetFinishedDeferreds();  
326 - that._transition($(this).find('.fileupload-progress')).done(  
327 - function () {  
328 - that._trigger('started', e);  
329 - }  
330 - );  
331 - },  
332 - // Callback for uploads stop, equivalent to the global ajaxStop event:  
333 - stop: function (e) {  
334 - if (e.isDefaultPrevented()) {  
335 - return false;  
336 - }  
337 - var that = $(this).data('blueimp-fileupload') ||  
338 - $(this).data('fileupload'),  
339 - deferred = that._addFinishedDeferreds();  
340 - $.when.apply($, that._getFinishedDeferreds())  
341 - .done(function () {  
342 - that._trigger('stopped', e);  
343 - });  
344 - that._transition($(this).find('.fileupload-progress')).done(  
345 - function () {  
346 - $(this).find('.progress')  
347 - .attr('aria-valuenow', '0')  
348 - .children().first().css('width', '0%');  
349 - $(this).find('.progress-extended').html('&nbsp;');  
350 - deferred.resolve();  
351 - }  
352 - );  
353 - },  
354 - processstart: function (e) {  
355 - if (e.isDefaultPrevented()) {  
356 - return false;  
357 - }  
358 - $(this).addClass('fileupload-processing');  
359 - },  
360 - processstop: function (e) {  
361 - if (e.isDefaultPrevented()) {  
362 - return false;  
363 - }  
364 - $(this).removeClass('fileupload-processing');  
365 - },  
366 - // Callback for file deletion:  
367 - destroy: function (e, data) {  
368 - if (e.isDefaultPrevented()) {  
369 - return false;  
370 - }  
371 - var that = $(this).data('blueimp-fileupload') ||  
372 - $(this).data('fileupload'),  
373 - removeNode = function () {  
374 - that._transition(data.context).done(  
375 - function () {  
376 - $(this).remove();  
377 - that._trigger('destroyed', e, data);  
378 - }  
379 - );  
380 - };  
381 - if (data.url) {  
382 - data.dataType = data.dataType || that.options.dataType;  
383 - $.ajax(data).done(removeNode).fail(function () {  
384 - that._trigger('destroyfailed', e, data);  
385 - });  
386 - } else {  
387 - removeNode();  
388 - }  
389 - }  
390 - },  
391 -  
392 - _resetFinishedDeferreds: function () {  
393 - this._finishedUploads = [];  
394 - },  
395 -  
396 - _addFinishedDeferreds: function (deferred) {  
397 - if (!deferred) {  
398 - deferred = $.Deferred();  
399 - }  
400 - this._finishedUploads.push(deferred);  
401 - return deferred;  
402 - },  
403 -  
404 - _getFinishedDeferreds: function () {  
405 - return this._finishedUploads;  
406 - },  
407 -  
408 - // Link handler, that allows to download files  
409 - // by drag & drop of the links to the desktop:  
410 - _enableDragToDesktop: function () {  
411 - var link = $(this),  
412 - url = link.prop('href'),  
413 - name = link.prop('download'),  
414 - type = 'application/octet-stream';  
415 - link.bind('dragstart', function (e) {  
416 - try {  
417 - e.originalEvent.dataTransfer.setData(  
418 - 'DownloadURL',  
419 - [type, name, url].join(':')  
420 - );  
421 - } catch (ignore) {}  
422 - });  
423 - },  
424 -  
425 - _formatFileSize: function (bytes) {  
426 - if (typeof bytes !== 'number') {  
427 - return '';  
428 - }  
429 - if (bytes >= 1000000000) {  
430 - return (bytes / 1000000000).toFixed(2) + ' GB';  
431 - }  
432 - if (bytes >= 1000000) {  
433 - return (bytes / 1000000).toFixed(2) + ' MB';  
434 - }  
435 - return (bytes / 1000).toFixed(2) + ' KB';  
436 - },  
437 -  
438 - _formatBitrate: function (bits) {  
439 - if (typeof bits !== 'number') {  
440 - return '';  
441 - }  
442 - if (bits >= 1000000000) {  
443 - return (bits / 1000000000).toFixed(2) + ' Gbit/s';  
444 - }  
445 - if (bits >= 1000000) {  
446 - return (bits / 1000000).toFixed(2) + ' Mbit/s';  
447 - }  
448 - if (bits >= 1000) {  
449 - return (bits / 1000).toFixed(2) + ' kbit/s';  
450 - }  
451 - return bits.toFixed(2) + ' bit/s';  
452 - },  
453 -  
454 - _formatTime: function (seconds) {  
455 - var date = new Date(seconds * 1000),  
456 - days = Math.floor(seconds / 86400);  
457 - days = days ? days + 'd ' : '';  
458 - return days +  
459 - ('0' + date.getUTCHours()).slice(-2) + ':' +  
460 - ('0' + date.getUTCMinutes()).slice(-2) + ':' +  
461 - ('0' + date.getUTCSeconds()).slice(-2);  
462 - },  
463 -  
464 - _formatPercentage: function (floatValue) {  
465 - return (floatValue * 100).toFixed(2) + ' %';  
466 - },  
467 -  
468 - _renderExtendedProgress: function (data) {  
469 - return this._formatBitrate(data.bitrate) + ' | ' +  
470 - this._formatTime(  
471 - (data.total - data.loaded) * 8 / data.bitrate  
472 - ) + ' | ' +  
473 - this._formatPercentage(  
474 - data.loaded / data.total  
475 - ) + ' | ' +  
476 - this._formatFileSize(data.loaded) + ' / ' +  
477 - this._formatFileSize(data.total);  
478 - },  
479 -  
480 - _renderTemplate: function (func, files) {  
481 - if (!func) {  
482 - return $();  
483 - }  
484 - var result = func({  
485 - files: files,  
486 - formatFileSize: this._formatFileSize,  
487 - options: this.options  
488 - });  
489 - if (result instanceof $) {  
490 - return result;  
491 - }  
492 - return $(this.options.templatesContainer).html(result).children();  
493 - },  
494 -  
495 - _renderPreviews: function (data) {  
496 - data.context.find('.preview').each(function (index, elm) {  
497 - $(elm).append(data.files[index].preview);  
498 - });  
499 - },  
500 -  
501 - _renderUpload: function (files) {  
502 - return this._renderTemplate(  
503 - this.options.uploadTemplate,  
504 - files  
505 - );  
506 - },  
507 -  
508 - _renderDownload: function (files) {  
509 - return this._renderTemplate(  
510 - this.options.downloadTemplate,  
511 - files  
512 - ).find('a[download]').each(this._enableDragToDesktop).end();  
513 - },  
514 -  
515 - _startHandler: function (e) {  
516 - e.preventDefault();  
517 - var button = $(e.currentTarget),  
518 - template = button.closest('.template-upload'),  
519 - data = template.data('data');  
520 - button.prop('disabled', true);  
521 - if (data && data.submit) {  
522 - data.submit();  
523 - }  
524 - },  
525 -  
526 - _cancelHandler: function (e) {  
527 - e.preventDefault();  
528 - var template = $(e.currentTarget)  
529 - .closest('.template-upload,.template-download'),  
530 - data = template.data('data') || {};  
531 - data.context = data.context || template;  
532 - if (data.abort) {  
533 - data.abort();  
534 - } else {  
535 - data.errorThrown = 'abort';  
536 - this._trigger('fail', e, data);  
537 - }  
538 - },  
539 -  
540 - _deleteHandler: function (e) {  
541 - e.preventDefault();  
542 - var button = $(e.currentTarget);  
543 - this._trigger('destroy', e, $.extend({  
544 - context: button.closest('.template-download'),  
545 - type: 'DELETE'  
546 - }, button.data()));  
547 - },  
548 -  
549 - _forceReflow: function (node) {  
550 - return $.support.transition && node.length &&  
551 - node[0].offsetWidth;  
552 - },  
553 -  
554 - _transition: function (node) {  
555 - var dfd = $.Deferred();  
556 - if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {  
557 - node.bind(  
558 - $.support.transition.end,  
559 - function (e) {  
560 - // Make sure we don't respond to other transitions events  
561 - // in the container element, e.g. from button elements:  
562 - if (e.target === node[0]) {  
563 - node.unbind($.support.transition.end);  
564 - dfd.resolveWith(node);  
565 - }  
566 - }  
567 - ).toggleClass('in');  
568 - } else {  
569 - node.toggleClass('in');  
570 - dfd.resolveWith(node);  
571 - }  
572 - return dfd;  
573 - },  
574 -  
575 - _initButtonBarEventHandlers: function () {  
576 - var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),  
577 - filesList = this.options.filesContainer;  
578 - this._on(fileUploadButtonBar.find('.start'), {  
579 - click: function (e) {  
580 - e.preventDefault();  
581 - filesList.find('.start').click();  
582 - }  
583 - });  
584 - this._on(fileUploadButtonBar.find('.cancel'), {  
585 - click: function (e) {  
586 - e.preventDefault();  
587 - filesList.find('.cancel').click();  
588 - }  
589 - });  
590 - this._on(fileUploadButtonBar.find('.delete'), {  
591 - click: function (e) {  
592 - e.preventDefault();  
593 - filesList.find('.toggle:checked')  
594 - .closest('.template-download')  
595 - .find('.delete').click();  
596 - fileUploadButtonBar.find('.toggle')  
597 - .prop('checked', false);  
598 - }  
599 - });  
600 - this._on(fileUploadButtonBar.find('.toggle'), {  
601 - change: function (e) {  
602 - filesList.find('.toggle').prop(  
603 - 'checked',  
604 - $(e.currentTarget).is(':checked')  
605 - );  
606 - }  
607 - });  
608 - },  
609 -  
610 - _destroyButtonBarEventHandlers: function () {  
611 - this._off(  
612 - this.element.find('.fileupload-buttonbar')  
613 - .find('.start, .cancel, .delete'),  
614 - 'click'  
615 - );  
616 - this._off(  
617 - this.element.find('.fileupload-buttonbar .toggle'),  
618 - 'change.'  
619 - );  
620 - },  
621 -  
622 - _initEventHandlers: function () {  
623 - this._super();  
624 - this._on(this.options.filesContainer, {  
625 - 'click .start': this._startHandler,  
626 - 'click .cancel': this._cancelHandler,  
627 - 'click .delete': this._deleteHandler  
628 - });  
629 - this._initButtonBarEventHandlers();  
630 - },  
631 -  
632 - _destroyEventHandlers: function () {  
633 - this._destroyButtonBarEventHandlers();  
634 - this._off(this.options.filesContainer, 'click');  
635 - this._super();  
636 - },  
637 -  
638 - _enableFileInputButton: function () {  
639 - this.element.find('.fileinput-button input')  
640 - .prop('disabled', false)  
641 - .parent().removeClass('disabled');  
642 - },  
643 -  
644 - _disableFileInputButton: function () {  
645 - this.element.find('.fileinput-button input')  
646 - .prop('disabled', true)  
647 - .parent().addClass('disabled');  
648 - },  
649 -  
650 - _initTemplates: function () {  
651 - var options = this.options;  
652 - options.templatesContainer = this.document[0].createElement(  
653 - options.filesContainer.prop('nodeName')  
654 - );  
655 - if (tmpl) {  
656 - if (options.uploadTemplateId) {  
657 - options.uploadTemplate = tmpl(options.uploadTemplateId);  
658 - }  
659 - if (options.downloadTemplateId) {  
660 - options.downloadTemplate = tmpl(options.downloadTemplateId);  
661 - }  
662 - }  
663 - },  
664 -  
665 - _initFilesContainer: function () {  
666 - var options = this.options;  
667 - if (options.filesContainer === undefined) {  
668 - options.filesContainer = this.element.find('.files');  
669 - } else if (!(options.filesContainer instanceof $)) {  
670 - options.filesContainer = $(options.filesContainer);  
671 - }  
672 - },  
673 -  
674 - _initSpecialOptions: function () {  
675 - this._super();  
676 - this._initFilesContainer();  
677 - this._initTemplates();  
678 - },  
679 -  
680 - _create: function () {  
681 - this._super();  
682 - this._resetFinishedDeferreds();  
683 - if (!$.support.fileInput) {  
684 - this._disableFileInputButton();  
685 - }  
686 - },  
687 -  
688 - enable: function () {  
689 - var wasDisabled = false;  
690 - if (this.options.disabled) {  
691 - wasDisabled = true;  
692 - }  
693 - this._super();  
694 - if (wasDisabled) {  
695 - this.element.find('input, button').prop('disabled', false);  
696 - this._enableFileInputButton();  
697 - }  
698 - },  
699 -  
700 - disable: function () {  
701 - if (!this.options.disabled) {  
702 - this.element.find('input, button').prop('disabled', true);  
703 - this._disableFileInputButton();  
704 - }  
705 - this._super();  
706 - }  
707 -  
708 - });  
709 -  
710 -}));  
artbox-file/assets/js/jquery.fileupload-validate.js deleted
1 -/*  
2 - * jQuery File Upload Validation Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2013, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* global define, require, window */  
13 -  
14 -(function (factory) {  
15 - 'use strict';  
16 - if (typeof define === 'function' && define.amd) {  
17 - // Register as an anonymous AMD module:  
18 - define([  
19 - 'jquery',  
20 - './jquery.fileupload-process'  
21 - ], factory);  
22 - } else if (typeof exports === 'object') {  
23 - // Node/CommonJS:  
24 - factory(require('jquery'));  
25 - } else {  
26 - // Browser globals:  
27 - factory(  
28 - window.jQuery  
29 - );  
30 - }  
31 -}(function ($) {  
32 - 'use strict';  
33 -  
34 - // Append to the default processQueue:  
35 - $.blueimp.fileupload.prototype.options.processQueue.push(  
36 - {  
37 - action: 'validate',  
38 - // Always trigger this action,  
39 - // even if the previous action was rejected:  
40 - always: true,  
41 - // Options taken from the global options map:  
42 - acceptFileTypes: '@',  
43 - maxFileSize: '@',  
44 - minFileSize: '@',  
45 - maxNumberOfFiles: '@',  
46 - disabled: '@disableValidation'  
47 - }  
48 - );  
49 -  
50 - // The File Upload Validation plugin extends the fileupload widget  
51 - // with file validation functionality:  
52 - $.widget('blueimp.fileupload', $.blueimp.fileupload, {  
53 -  
54 - options: {  
55 - /*  
56 - // The regular expression for allowed file types, matches  
57 - // against either file type or file name:  
58 - acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,  
59 - // The maximum allowed file size in bytes:  
60 - maxFileSize: 10000000, // 10 MB  
61 - // The minimum allowed file size in bytes:  
62 - minFileSize: undefined, // No minimal file size  
63 - // The limit of files to be uploaded:  
64 - maxNumberOfFiles: 10,  
65 - */  
66 -  
67 - // Function returning the current number of files,  
68 - // has to be overriden for maxNumberOfFiles validation:  
69 - getNumberOfFiles: $.noop,  
70 -  
71 - // Error and info messages:  
72 - messages: {  
73 - maxNumberOfFiles: 'Maximum number of files exceeded',  
74 - acceptFileTypes: 'File type not allowed',  
75 - maxFileSize: 'File is too large',  
76 - minFileSize: 'File is too small'  
77 - }  
78 - },  
79 -  
80 - processActions: {  
81 -  
82 - validate: function (data, options) {  
83 - if (options.disabled) {  
84 - return data;  
85 - }  
86 - var dfd = $.Deferred(),  
87 - settings = this.options,  
88 - file = data.files[data.index],  
89 - fileSize;  
90 - if (options.minFileSize || options.maxFileSize) {  
91 - fileSize = file.size;  
92 - }  
93 - if ($.type(options.maxNumberOfFiles) === 'number' &&  
94 - (settings.getNumberOfFiles() || 0) + data.files.length >  
95 - options.maxNumberOfFiles) {  
96 - file.error = settings.i18n('maxNumberOfFiles');  
97 - } else if (options.acceptFileTypes &&  
98 - !(options.acceptFileTypes.test(file.type) ||  
99 - options.acceptFileTypes.test(file.name))) {  
100 - file.error = settings.i18n('acceptFileTypes');  
101 - } else if (fileSize > options.maxFileSize) {  
102 - file.error = settings.i18n('maxFileSize');  
103 - } else if ($.type(fileSize) === 'number' &&  
104 - fileSize < options.minFileSize) {  
105 - file.error = settings.i18n('minFileSize');  
106 - } else {  
107 - delete file.error;  
108 - }  
109 - if (file.error || data.files.error) {  
110 - data.files.error = true;  
111 - dfd.rejectWith(this, [data]);  
112 - } else {  
113 - dfd.resolveWith(this, [data]);  
114 - }  
115 - return dfd.promise();  
116 - }  
117 -  
118 - }  
119 -  
120 - });  
121 -  
122 -}));  
artbox-file/assets/js/jquery.fileupload-video.js deleted
1 -/*  
2 - * jQuery File Upload Video Preview Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2013, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* jshint nomen:false */  
13 -/* global define, require, window, document */  
14 -  
15 -(function (factory) {  
16 - 'use strict';  
17 - if (typeof define === 'function' && define.amd) {  
18 - // Register as an anonymous AMD module:  
19 - define([  
20 - 'jquery',  
21 - 'load-image',  
22 - './jquery.fileupload-process'  
23 - ], factory);  
24 - } else if (typeof exports === 'object') {  
25 - // Node/CommonJS:  
26 - factory(  
27 - require('jquery'),  
28 - require('load-image')  
29 - );  
30 - } else {  
31 - // Browser globals:  
32 - factory(  
33 - window.jQuery,  
34 - window.loadImage  
35 - );  
36 - }  
37 -}(function ($, loadImage) {  
38 - 'use strict';  
39 -  
40 - // Prepend to the default processQueue:  
41 - $.blueimp.fileupload.prototype.options.processQueue.unshift(  
42 - {  
43 - action: 'loadVideo',  
44 - // Use the action as prefix for the "@" options:  
45 - prefix: true,  
46 - fileTypes: '@',  
47 - maxFileSize: '@',  
48 - disabled: '@disableVideoPreview'  
49 - },  
50 - {  
51 - action: 'setVideo',  
52 - name: '@videoPreviewName',  
53 - disabled: '@disableVideoPreview'  
54 - }  
55 - );  
56 -  
57 - // The File Upload Video Preview plugin extends the fileupload widget  
58 - // with video preview functionality:  
59 - $.widget('blueimp.fileupload', $.blueimp.fileupload, {  
60 -  
61 - options: {  
62 - // The regular expression for the types of video files to load,  
63 - // matched against the file type:  
64 - loadVideoFileTypes: /^video\/.*$/  
65 - },  
66 -  
67 - _videoElement: document.createElement('video'),  
68 -  
69 - processActions: {  
70 -  
71 - // Loads the video file given via data.files and data.index  
72 - // as video element if the browser supports playing it.  
73 - // Accepts the options fileTypes (regular expression)  
74 - // and maxFileSize (integer) to limit the files to load:  
75 - loadVideo: function (data, options) {  
76 - if (options.disabled) {  
77 - return data;  
78 - }  
79 - var file = data.files[data.index],  
80 - url,  
81 - video;  
82 - if (this._videoElement.canPlayType &&  
83 - this._videoElement.canPlayType(file.type) &&  
84 - ($.type(options.maxFileSize) !== 'number' ||  
85 - file.size <= options.maxFileSize) &&  
86 - (!options.fileTypes ||  
87 - options.fileTypes.test(file.type))) {  
88 - url = loadImage.createObjectURL(file);  
89 - if (url) {  
90 - video = this._videoElement.cloneNode(false);  
91 - video.src = url;  
92 - video.controls = true;  
93 - data.video = video;  
94 - return data;  
95 - }  
96 - }  
97 - return data;  
98 - },  
99 -  
100 - // Sets the video element as a property of the file object:  
101 - setVideo: function (data, options) {  
102 - if (data.video && !options.disabled) {  
103 - data.files[data.index][options.name || 'preview'] = data.video;  
104 - }  
105 - return data;  
106 - }  
107 -  
108 - }  
109 -  
110 - });  
111 -  
112 -}));  
artbox-file/assets/js/jquery.fileupload.js deleted
1 -/*  
2 - * jQuery File Upload Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2010, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* jshint nomen:false */  
13 -/* global define, require, window, document, location, Blob, FormData */  
14 -  
15 -(function (factory) {  
16 - 'use strict';  
17 - if (typeof define === 'function' && define.amd) {  
18 - // Register as an anonymous AMD module:  
19 - define([  
20 - 'jquery',  
21 - 'jquery.ui.widget'  
22 - ], factory);  
23 - } else if (typeof exports === 'object') {  
24 - // Node/CommonJS:  
25 - factory(  
26 - require('jquery'),  
27 - require('./vendor/jquery.ui.widget')  
28 - );  
29 - } else {  
30 - // Browser globals:  
31 - factory(window.jQuery);  
32 - }  
33 -}(function ($) {  
34 - 'use strict';  
35 -  
36 - // Detect file input support, based on  
37 - // http://viljamis.com/blog/2012/file-upload-support-on-mobile/  
38 - $.support.fileInput = !(new RegExp(  
39 - // Handle devices which give false positives for the feature detection:  
40 - '(Android (1\\.[0156]|2\\.[01]))' +  
41 - '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +  
42 - '|(w(eb)?OSBrowser)|(webOS)' +  
43 - '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'  
44 - ).test(window.navigator.userAgent) ||  
45 - // Feature detection for all other devices:  
46 - $('<input type="file">').prop('disabled'));  
47 -  
48 - // The FileReader API is not actually used, but works as feature detection,  
49 - // as some Safari versions (5?) support XHR file uploads via the FormData API,  
50 - // but not non-multipart XHR file uploads.  
51 - // window.XMLHttpRequestUpload is not available on IE10, so we check for  
52 - // window.ProgressEvent instead to detect XHR2 file upload capability:  
53 - $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);  
54 - $.support.xhrFormDataFileUpload = !!window.FormData;  
55 -  
56 - // Detect support for Blob slicing (required for chunked uploads):  
57 - $.support.blobSlice = window.Blob && (Blob.prototype.slice ||  
58 - Blob.prototype.webkitSlice || Blob.prototype.mozSlice);  
59 -  
60 - // Helper function to create drag handlers for dragover/dragenter/dragleave:  
61 - function getDragHandler(type) {  
62 - var isDragOver = type === 'dragover';  
63 - return function (e) {  
64 - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;  
65 - var dataTransfer = e.dataTransfer;  
66 - if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&  
67 - this._trigger(  
68 - type,  
69 - $.Event(type, {delegatedEvent: e})  
70 - ) !== false) {  
71 - e.preventDefault();  
72 - if (isDragOver) {  
73 - dataTransfer.dropEffect = 'copy';  
74 - }  
75 - }  
76 - };  
77 - }  
78 -  
79 - // The fileupload widget listens for change events on file input fields defined  
80 - // via fileInput setting and paste or drop events of the given dropZone.  
81 - // In addition to the default jQuery Widget methods, the fileupload widget  
82 - // exposes the "add" and "send" methods, to add or directly send files using  
83 - // the fileupload API.  
84 - // By default, files added via file input selection, paste, drag & drop or  
85 - // "add" method are uploaded immediately, but it is possible to override  
86 - // the "add" callback option to queue file uploads.  
87 - $.widget('blueimp.fileupload', {  
88 -  
89 - options: {  
90 - // The drop target element(s), by the default the complete document.  
91 - // Set to null to disable drag & drop support:  
92 - dropZone: $(document),  
93 - // The paste target element(s), by the default undefined.  
94 - // Set to a DOM node or jQuery object to enable file pasting:  
95 - pasteZone: undefined,  
96 - // The file input field(s), that are listened to for change events.  
97 - // If undefined, it is set to the file input fields inside  
98 - // of the widget element on plugin initialization.  
99 - // Set to null to disable the change listener.  
100 - fileInput: undefined,  
101 - // By default, the file input field is replaced with a clone after  
102 - // each input field change event. This is required for iframe transport  
103 - // queues and allows change events to be fired for the same file  
104 - // selection, but can be disabled by setting the following option to false:  
105 - replaceFileInput: true,  
106 - // The parameter name for the file form data (the request argument name).  
107 - // If undefined or empty, the name property of the file input field is  
108 - // used, or "files[]" if the file input name property is also empty,  
109 - // can be a string or an array of strings:  
110 - paramName: undefined,  
111 - // By default, each file of a selection is uploaded using an individual  
112 - // request for XHR type uploads. Set to false to upload file  
113 - // selections in one request each:  
114 - singleFileUploads: true,  
115 - // To limit the number of files uploaded with one XHR request,  
116 - // set the following option to an integer greater than 0:  
117 - limitMultiFileUploads: undefined,  
118 - // The following option limits the number of files uploaded with one  
119 - // XHR request to keep the request size under or equal to the defined  
120 - // limit in bytes:  
121 - limitMultiFileUploadSize: undefined,  
122 - // Multipart file uploads add a number of bytes to each uploaded file,  
123 - // therefore the following option adds an overhead for each file used  
124 - // in the limitMultiFileUploadSize configuration:  
125 - limitMultiFileUploadSizeOverhead: 512,  
126 - // Set the following option to true to issue all file upload requests  
127 - // in a sequential order:  
128 - sequentialUploads: false,  
129 - // To limit the number of concurrent uploads,  
130 - // set the following option to an integer greater than 0:  
131 - limitConcurrentUploads: undefined,  
132 - // Set the following option to true to force iframe transport uploads:  
133 - forceIframeTransport: false,  
134 - // Set the following option to the location of a redirect url on the  
135 - // origin server, for cross-domain iframe transport uploads:  
136 - redirect: undefined,  
137 - // The parameter name for the redirect url, sent as part of the form  
138 - // data and set to 'redirect' if this option is empty:  
139 - redirectParamName: undefined,  
140 - // Set the following option to the location of a postMessage window,  
141 - // to enable postMessage transport uploads:  
142 - postMessage: undefined,  
143 - // By default, XHR file uploads are sent as multipart/form-data.  
144 - // The iframe transport is always using multipart/form-data.  
145 - // Set to false to enable non-multipart XHR uploads:  
146 - multipart: true,  
147 - // To upload large files in smaller chunks, set the following option  
148 - // to a preferred maximum chunk size. If set to 0, null or undefined,  
149 - // or the browser does not support the required Blob API, files will  
150 - // be uploaded as a whole.  
151 - maxChunkSize: undefined,  
152 - // When a non-multipart upload or a chunked multipart upload has been  
153 - // aborted, this option can be used to resume the upload by setting  
154 - // it to the size of the already uploaded bytes. This option is most  
155 - // useful when modifying the options object inside of the "add" or  
156 - // "send" callbacks, as the options are cloned for each file upload.  
157 - uploadedBytes: undefined,  
158 - // By default, failed (abort or error) file uploads are removed from the  
159 - // global progress calculation. Set the following option to false to  
160 - // prevent recalculating the global progress data:  
161 - recalculateProgress: true,  
162 - // Interval in milliseconds to calculate and trigger progress events:  
163 - progressInterval: 100,  
164 - // Interval in milliseconds to calculate progress bitrate:  
165 - bitrateInterval: 500,  
166 - // By default, uploads are started automatically when adding files:  
167 - autoUpload: true,  
168 -  
169 - // Error and info messages:  
170 - messages: {  
171 - uploadedBytes: 'Uploaded bytes exceed file size'  
172 - },  
173 -  
174 - // Translation function, gets the message key to be translated  
175 - // and an object with context specific data as arguments:  
176 - i18n: function (message, context) {  
177 - message = this.messages[message] || message.toString();  
178 - if (context) {  
179 - $.each(context, function (key, value) {  
180 - message = message.replace('{' + key + '}', value);  
181 - });  
182 - }  
183 - return message;  
184 - },  
185 -  
186 - // Additional form data to be sent along with the file uploads can be set  
187 - // using this option, which accepts an array of objects with name and  
188 - // value properties, a function returning such an array, a FormData  
189 - // object (for XHR file uploads), or a simple object.  
190 - // The form of the first fileInput is given as parameter to the function:  
191 - formData: function (form) {  
192 - return form.serializeArray();  
193 - },  
194 -  
195 - // The add callback is invoked as soon as files are added to the fileupload  
196 - // widget (via file input selection, drag & drop, paste or add API call).  
197 - // If the singleFileUploads option is enabled, this callback will be  
198 - // called once for each file in the selection for XHR file uploads, else  
199 - // once for each file selection.  
200 - //  
201 - // The upload starts when the submit method is invoked on the data parameter.  
202 - // The data object contains a files property holding the added files  
203 - // and allows you to override plugin options as well as define ajax settings.  
204 - //  
205 - // Listeners for this callback can also be bound the following way:  
206 - // .bind('fileuploadadd', func);  
207 - //  
208 - // data.submit() returns a Promise object and allows to attach additional  
209 - // handlers using jQuery's Deferred callbacks:  
210 - // data.submit().done(func).fail(func).always(func);  
211 - add: function (e, data) {  
212 - if (e.isDefaultPrevented()) {  
213 - return false;  
214 - }  
215 - if (data.autoUpload || (data.autoUpload !== false &&  
216 - $(this).fileupload('option', 'autoUpload'))) {  
217 - data.process().done(function () {  
218 - data.submit();  
219 - });  
220 - }  
221 - },  
222 -  
223 - // Other callbacks:  
224 -  
225 - // Callback for the submit event of each file upload:  
226 - // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);  
227 -  
228 - // Callback for the start of each file upload request:  
229 - // send: function (e, data) {}, // .bind('fileuploadsend', func);  
230 -  
231 - // Callback for successful uploads:  
232 - // done: function (e, data) {}, // .bind('fileuploaddone', func);  
233 -  
234 - // Callback for failed (abort or error) uploads:  
235 - // fail: function (e, data) {}, // .bind('fileuploadfail', func);  
236 -  
237 - // Callback for completed (success, abort or error) requests:  
238 - // always: function (e, data) {}, // .bind('fileuploadalways', func);  
239 -  
240 - // Callback for upload progress events:  
241 - // progress: function (e, data) {}, // .bind('fileuploadprogress', func);  
242 -  
243 - // Callback for global upload progress events:  
244 - // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);  
245 -  
246 - // Callback for uploads start, equivalent to the global ajaxStart event:  
247 - // start: function (e) {}, // .bind('fileuploadstart', func);  
248 -  
249 - // Callback for uploads stop, equivalent to the global ajaxStop event:  
250 - // stop: function (e) {}, // .bind('fileuploadstop', func);  
251 -  
252 - // Callback for change events of the fileInput(s):  
253 - // change: function (e, data) {}, // .bind('fileuploadchange', func);  
254 -  
255 - // Callback for paste events to the pasteZone(s):  
256 - // paste: function (e, data) {}, // .bind('fileuploadpaste', func);  
257 -  
258 - // Callback for drop events of the dropZone(s):  
259 - // drop: function (e, data) {}, // .bind('fileuploaddrop', func);  
260 -  
261 - // Callback for dragover events of the dropZone(s):  
262 - // dragover: function (e) {}, // .bind('fileuploaddragover', func);  
263 -  
264 - // Callback for the start of each chunk upload request:  
265 - // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);  
266 -  
267 - // Callback for successful chunk uploads:  
268 - // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);  
269 -  
270 - // Callback for failed (abort or error) chunk uploads:  
271 - // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);  
272 -  
273 - // Callback for completed (success, abort or error) chunk upload requests:  
274 - // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);  
275 -  
276 - // The plugin options are used as settings object for the ajax calls.  
277 - // The following are jQuery ajax settings required for the file uploads:  
278 - processData: false,  
279 - contentType: false,  
280 - cache: false,  
281 - timeout: 0  
282 - },  
283 -  
284 - // A list of options that require reinitializing event listeners and/or  
285 - // special initialization code:  
286 - _specialOptions: [  
287 - 'fileInput',  
288 - 'dropZone',  
289 - 'pasteZone',  
290 - 'multipart',  
291 - 'forceIframeTransport'  
292 - ],  
293 -  
294 - _blobSlice: $.support.blobSlice && function () {  
295 - var slice = this.slice || this.webkitSlice || this.mozSlice;  
296 - return slice.apply(this, arguments);  
297 - },  
298 -  
299 - _BitrateTimer: function () {  
300 - this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());  
301 - this.loaded = 0;  
302 - this.bitrate = 0;  
303 - this.getBitrate = function (now, loaded, interval) {  
304 - var timeDiff = now - this.timestamp;  
305 - if (!this.bitrate || !interval || timeDiff > interval) {  
306 - this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;  
307 - this.loaded = loaded;  
308 - this.timestamp = now;  
309 - }  
310 - return this.bitrate;  
311 - };  
312 - },  
313 -  
314 - _isXHRUpload: function (options) {  
315 - return !options.forceIframeTransport &&  
316 - ((!options.multipart && $.support.xhrFileUpload) ||  
317 - $.support.xhrFormDataFileUpload);  
318 - },  
319 -  
320 - _getFormData: function (options) {  
321 - var formData;  
322 - if ($.type(options.formData) === 'function') {  
323 - return options.formData(options.form);  
324 - }  
325 - if ($.isArray(options.formData)) {  
326 - return options.formData;  
327 - }  
328 - if ($.type(options.formData) === 'object') {  
329 - formData = [];  
330 - $.each(options.formData, function (name, value) {  
331 - formData.push({name: name, value: value});  
332 - });  
333 - return formData;  
334 - }  
335 - return [];  
336 - },  
337 -  
338 - _getTotal: function (files) {  
339 - var total = 0;  
340 - $.each(files, function (index, file) {  
341 - total += file.size || 1;  
342 - });  
343 - return total;  
344 - },  
345 -  
346 - _initProgressObject: function (obj) {  
347 - var progress = {  
348 - loaded: 0,  
349 - total: 0,  
350 - bitrate: 0  
351 - };  
352 - if (obj._progress) {  
353 - $.extend(obj._progress, progress);  
354 - } else {  
355 - obj._progress = progress;  
356 - }  
357 - },  
358 -  
359 - _initResponseObject: function (obj) {  
360 - var prop;  
361 - if (obj._response) {  
362 - for (prop in obj._response) {  
363 - if (obj._response.hasOwnProperty(prop)) {  
364 - delete obj._response[prop];  
365 - }  
366 - }  
367 - } else {  
368 - obj._response = {};  
369 - }  
370 - },  
371 -  
372 - _onProgress: function (e, data) {  
373 - if (e.lengthComputable) {  
374 - var now = ((Date.now) ? Date.now() : (new Date()).getTime()),  
375 - loaded;  
376 - if (data._time && data.progressInterval &&  
377 - (now - data._time < data.progressInterval) &&  
378 - e.loaded !== e.total) {  
379 - return;  
380 - }  
381 - data._time = now;  
382 - loaded = Math.floor(  
383 - e.loaded / e.total * (data.chunkSize || data._progress.total)  
384 - ) + (data.uploadedBytes || 0);  
385 - // Add the difference from the previously loaded state  
386 - // to the global loaded counter:  
387 - this._progress.loaded += (loaded - data._progress.loaded);  
388 - this._progress.bitrate = this._bitrateTimer.getBitrate(  
389 - now,  
390 - this._progress.loaded,  
391 - data.bitrateInterval  
392 - );  
393 - data._progress.loaded = data.loaded = loaded;  
394 - data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(  
395 - now,  
396 - loaded,  
397 - data.bitrateInterval  
398 - );  
399 - // Trigger a custom progress event with a total data property set  
400 - // to the file size(s) of the current upload and a loaded data  
401 - // property calculated accordingly:  
402 - this._trigger(  
403 - 'progress',  
404 - $.Event('progress', {delegatedEvent: e}),  
405 - data  
406 - );  
407 - // Trigger a global progress event for all current file uploads,  
408 - // including ajax calls queued for sequential file uploads:  
409 - this._trigger(  
410 - 'progressall',  
411 - $.Event('progressall', {delegatedEvent: e}),  
412 - this._progress  
413 - );  
414 - }  
415 - },  
416 -  
417 - _initProgressListener: function (options) {  
418 - var that = this,  
419 - xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();  
420 - // Accesss to the native XHR object is required to add event listeners  
421 - // for the upload progress event:  
422 - if (xhr.upload) {  
423 - $(xhr.upload).bind('progress', function (e) {  
424 - var oe = e.originalEvent;  
425 - // Make sure the progress event properties get copied over:  
426 - e.lengthComputable = oe.lengthComputable;  
427 - e.loaded = oe.loaded;  
428 - e.total = oe.total;  
429 - that._onProgress(e, options);  
430 - });  
431 - options.xhr = function () {  
432 - return xhr;  
433 - };  
434 - }  
435 - },  
436 -  
437 - _isInstanceOf: function (type, obj) {  
438 - // Cross-frame instanceof check  
439 - return Object.prototype.toString.call(obj) === '[object ' + type + ']';  
440 - },  
441 -  
442 - _initXHRData: function (options) {  
443 - var that = this,  
444 - formData,  
445 - file = options.files[0],  
446 - // Ignore non-multipart setting if not supported:  
447 - multipart = options.multipart || !$.support.xhrFileUpload,  
448 - paramName = $.type(options.paramName) === 'array' ?  
449 - options.paramName[0] : options.paramName;  
450 - options.headers = $.extend({}, options.headers);  
451 - if (options.contentRange) {  
452 - options.headers['Content-Range'] = options.contentRange;  
453 - }  
454 - if (!multipart || options.blob || !this._isInstanceOf('File', file)) {  
455 - options.headers['Content-Disposition'] = 'attachment; filename="' +  
456 - encodeURI(file.name) + '"';  
457 - }  
458 - if (!multipart) {  
459 - options.contentType = file.type || 'application/octet-stream';  
460 - options.data = options.blob || file;  
461 - } else if ($.support.xhrFormDataFileUpload) {  
462 - if (options.postMessage) {  
463 - // window.postMessage does not allow sending FormData  
464 - // objects, so we just add the File/Blob objects to  
465 - // the formData array and let the postMessage window  
466 - // create the FormData object out of this array:  
467 - formData = this._getFormData(options);  
468 - if (options.blob) {  
469 - formData.push({  
470 - name: paramName,  
471 - value: options.blob  
472 - });  
473 - } else {  
474 - $.each(options.files, function (index, file) {  
475 - formData.push({  
476 - name: ($.type(options.paramName) === 'array' &&  
477 - options.paramName[index]) || paramName,  
478 - value: file  
479 - });  
480 - });  
481 - }  
482 - } else {  
483 - if (that._isInstanceOf('FormData', options.formData)) {  
484 - formData = options.formData;  
485 - } else {  
486 - formData = new FormData();  
487 - $.each(this._getFormData(options), function (index, field) {  
488 - formData.append(field.name, field.value);  
489 - });  
490 - }  
491 - if (options.blob) {  
492 - formData.append(paramName, options.blob, file.name);  
493 - } else {  
494 - $.each(options.files, function (index, file) {  
495 - // This check allows the tests to run with  
496 - // dummy objects:  
497 - if (that._isInstanceOf('File', file) ||  
498 - that._isInstanceOf('Blob', file)) {  
499 - formData.append(  
500 - ($.type(options.paramName) === 'array' &&  
501 - options.paramName[index]) || paramName,  
502 - file,  
503 - file.uploadName || file.name  
504 - );  
505 - }  
506 - });  
507 - }  
508 - }  
509 - options.data = formData;  
510 - }  
511 - // Blob reference is not needed anymore, free memory:  
512 - options.blob = null;  
513 - },  
514 -  
515 - _initIframeSettings: function (options) {  
516 - var targetHost = $('<a></a>').prop('href', options.url).prop('host');  
517 - // Setting the dataType to iframe enables the iframe transport:  
518 - options.dataType = 'iframe ' + (options.dataType || '');  
519 - // The iframe transport accepts a serialized array as form data:  
520 - options.formData = this._getFormData(options);  
521 - // Add redirect url to form data on cross-domain uploads:  
522 - if (options.redirect && targetHost && targetHost !== location.host) {  
523 - options.formData.push({  
524 - name: options.redirectParamName || 'redirect',  
525 - value: options.redirect  
526 - });  
527 - }  
528 - },  
529 -  
530 - _initDataSettings: function (options) {  
531 - if (this._isXHRUpload(options)) {  
532 - if (!this._chunkedUpload(options, true)) {  
533 - if (!options.data) {  
534 - this._initXHRData(options);  
535 - }  
536 - this._initProgressListener(options);  
537 - }  
538 - if (options.postMessage) {  
539 - // Setting the dataType to postmessage enables the  
540 - // postMessage transport:  
541 - options.dataType = 'postmessage ' + (options.dataType || '');  
542 - }  
543 - } else {  
544 - this._initIframeSettings(options);  
545 - }  
546 - },  
547 -  
548 - _getParamName: function (options) {  
549 - var fileInput = $(options.fileInput),  
550 - paramName = options.paramName;  
551 - if (!paramName) {  
552 - paramName = [];  
553 - fileInput.each(function () {  
554 - var input = $(this),  
555 - name = input.prop('name') || 'files[]',  
556 - i = (input.prop('files') || [1]).length;  
557 - while (i) {  
558 - paramName.push(name);  
559 - i -= 1;  
560 - }  
561 - });  
562 - if (!paramName.length) {  
563 - paramName = [fileInput.prop('name') || 'files[]'];  
564 - }  
565 - } else if (!$.isArray(paramName)) {  
566 - paramName = [paramName];  
567 - }  
568 - return paramName;  
569 - },  
570 -  
571 - _initFormSettings: function (options) {  
572 - // Retrieve missing options from the input field and the  
573 - // associated form, if available:  
574 - if (!options.form || !options.form.length) {  
575 - options.form = $(options.fileInput.prop('form'));  
576 - // If the given file input doesn't have an associated form,  
577 - // use the default widget file input's form:  
578 - if (!options.form.length) {  
579 - options.form = $(this.options.fileInput.prop('form'));  
580 - }  
581 - }  
582 - options.paramName = this._getParamName(options);  
583 - if (!options.url) {  
584 - options.url = options.form.prop('action') || location.href;  
585 - }  
586 - // The HTTP request method must be "POST" or "PUT":  
587 - options.type = (options.type ||  
588 - ($.type(options.form.prop('method')) === 'string' &&  
589 - options.form.prop('method')) || ''  
590 - ).toUpperCase();  
591 - if (options.type !== 'POST' && options.type !== 'PUT' &&  
592 - options.type !== 'PATCH') {  
593 - options.type = 'POST';  
594 - }  
595 - if (!options.formAcceptCharset) {  
596 - options.formAcceptCharset = options.form.attr('accept-charset');  
597 - }  
598 - },  
599 -  
600 - _getAJAXSettings: function (data) {  
601 - var options = $.extend({}, this.options, data);  
602 - this._initFormSettings(options);  
603 - this._initDataSettings(options);  
604 - return options;  
605 - },  
606 -  
607 - // jQuery 1.6 doesn't provide .state(),  
608 - // while jQuery 1.8+ removed .isRejected() and .isResolved():  
609 - _getDeferredState: function (deferred) {  
610 - if (deferred.state) {  
611 - return deferred.state();  
612 - }  
613 - if (deferred.isResolved()) {  
614 - return 'resolved';  
615 - }  
616 - if (deferred.isRejected()) {  
617 - return 'rejected';  
618 - }  
619 - return 'pending';  
620 - },  
621 -  
622 - // Maps jqXHR callbacks to the equivalent  
623 - // methods of the given Promise object:  
624 - _enhancePromise: function (promise) {  
625 - promise.success = promise.done;  
626 - promise.error = promise.fail;  
627 - promise.complete = promise.always;  
628 - return promise;  
629 - },  
630 -  
631 - // Creates and returns a Promise object enhanced with  
632 - // the jqXHR methods abort, success, error and complete:  
633 - _getXHRPromise: function (resolveOrReject, context, args) {  
634 - var dfd = $.Deferred(),  
635 - promise = dfd.promise();  
636 - context = context || this.options.context || promise;  
637 - if (resolveOrReject === true) {  
638 - dfd.resolveWith(context, args);  
639 - } else if (resolveOrReject === false) {  
640 - dfd.rejectWith(context, args);  
641 - }  
642 - promise.abort = dfd.promise;  
643 - return this._enhancePromise(promise);  
644 - },  
645 -  
646 - // Adds convenience methods to the data callback argument:  
647 - _addConvenienceMethods: function (e, data) {  
648 - var that = this,  
649 - getPromise = function (args) {  
650 - return $.Deferred().resolveWith(that, args).promise();  
651 - };  
652 - data.process = function (resolveFunc, rejectFunc) {  
653 - if (resolveFunc || rejectFunc) {  
654 - data._processQueue = this._processQueue =  
655 - (this._processQueue || getPromise([this])).pipe(  
656 - function () {  
657 - if (data.errorThrown) {  
658 - return $.Deferred()  
659 - .rejectWith(that, [data]).promise();  
660 - }  
661 - return getPromise(arguments);  
662 - }  
663 - ).pipe(resolveFunc, rejectFunc);  
664 - }  
665 - return this._processQueue || getPromise([this]);  
666 - };  
667 - data.submit = function () {  
668 - if (this.state() !== 'pending') {  
669 - data.jqXHR = this.jqXHR =  
670 - (that._trigger(  
671 - 'submit',  
672 - $.Event('submit', {delegatedEvent: e}),  
673 - this  
674 - ) !== false) && that._onSend(e, this);  
675 - }  
676 - return this.jqXHR || that._getXHRPromise();  
677 - };  
678 - data.abort = function () {  
679 - if (this.jqXHR) {  
680 - return this.jqXHR.abort();  
681 - }  
682 - this.errorThrown = 'abort';  
683 - that._trigger('fail', null, this);  
684 - return that._getXHRPromise(false);  
685 - };  
686 - data.state = function () {  
687 - if (this.jqXHR) {  
688 - return that._getDeferredState(this.jqXHR);  
689 - }  
690 - if (this._processQueue) {  
691 - return that._getDeferredState(this._processQueue);  
692 - }  
693 - };  
694 - data.processing = function () {  
695 - return !this.jqXHR && this._processQueue && that  
696 - ._getDeferredState(this._processQueue) === 'pending';  
697 - };  
698 - data.progress = function () {  
699 - return this._progress;  
700 - };  
701 - data.response = function () {  
702 - return this._response;  
703 - };  
704 - },  
705 -  
706 - // Parses the Range header from the server response  
707 - // and returns the uploaded bytes:  
708 - _getUploadedBytes: function (jqXHR) {  
709 - var range = jqXHR.getResponseHeader('Range'),  
710 - parts = range && range.split('-'),  
711 - upperBytesPos = parts && parts.length > 1 &&  
712 - parseInt(parts[1], 10);  
713 - return upperBytesPos && upperBytesPos + 1;  
714 - },  
715 -  
716 - // Uploads a file in multiple, sequential requests  
717 - // by splitting the file up in multiple blob chunks.  
718 - // If the second parameter is true, only tests if the file  
719 - // should be uploaded in chunks, but does not invoke any  
720 - // upload requests:  
721 - _chunkedUpload: function (options, testOnly) {  
722 - options.uploadedBytes = options.uploadedBytes || 0;  
723 - var that = this,  
724 - file = options.files[0],  
725 - fs = file.size,  
726 - ub = options.uploadedBytes,  
727 - mcs = options.maxChunkSize || fs,  
728 - slice = this._blobSlice,  
729 - dfd = $.Deferred(),  
730 - promise = dfd.promise(),  
731 - jqXHR,  
732 - upload;  
733 - if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||  
734 - options.data) {  
735 - return false;  
736 - }  
737 - if (testOnly) {  
738 - return true;  
739 - }  
740 - if (ub >= fs) {  
741 - file.error = options.i18n('uploadedBytes');  
742 - return this._getXHRPromise(  
743 - false,  
744 - options.context,  
745 - [null, 'error', file.error]  
746 - );  
747 - }  
748 - // The chunk upload method:  
749 - upload = function () {  
750 - // Clone the options object for each chunk upload:  
751 - var o = $.extend({}, options),  
752 - currentLoaded = o._progress.loaded;  
753 - o.blob = slice.call(  
754 - file,  
755 - ub,  
756 - ub + mcs,  
757 - file.type  
758 - );  
759 - // Store the current chunk size, as the blob itself  
760 - // will be dereferenced after data processing:  
761 - o.chunkSize = o.blob.size;  
762 - // Expose the chunk bytes position range:  
763 - o.contentRange = 'bytes ' + ub + '-' +  
764 - (ub + o.chunkSize - 1) + '/' + fs;  
765 - // Process the upload data (the blob and potential form data):  
766 - that._initXHRData(o);  
767 - // Add progress listeners for this chunk upload:  
768 - that._initProgressListener(o);  
769 - jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||  
770 - that._getXHRPromise(false, o.context))  
771 - .done(function (result, textStatus, jqXHR) {  
772 - ub = that._getUploadedBytes(jqXHR) ||  
773 - (ub + o.chunkSize);  
774 - // Create a progress event if no final progress event  
775 - // with loaded equaling total has been triggered  
776 - // for this chunk:  
777 - if (currentLoaded + o.chunkSize - o._progress.loaded) {  
778 - that._onProgress($.Event('progress', {  
779 - lengthComputable: true,  
780 - loaded: ub - o.uploadedBytes,  
781 - total: ub - o.uploadedBytes  
782 - }), o);  
783 - }  
784 - options.uploadedBytes = o.uploadedBytes = ub;  
785 - o.result = result;  
786 - o.textStatus = textStatus;  
787 - o.jqXHR = jqXHR;  
788 - that._trigger('chunkdone', null, o);  
789 - that._trigger('chunkalways', null, o);  
790 - if (ub < fs) {  
791 - // File upload not yet complete,  
792 - // continue with the next chunk:  
793 - upload();  
794 - } else {  
795 - dfd.resolveWith(  
796 - o.context,  
797 - [result, textStatus, jqXHR]  
798 - );  
799 - }  
800 - })  
801 - .fail(function (jqXHR, textStatus, errorThrown) {  
802 - o.jqXHR = jqXHR;  
803 - o.textStatus = textStatus;  
804 - o.errorThrown = errorThrown;  
805 - that._trigger('chunkfail', null, o);  
806 - that._trigger('chunkalways', null, o);  
807 - dfd.rejectWith(  
808 - o.context,  
809 - [jqXHR, textStatus, errorThrown]  
810 - );  
811 - });  
812 - };  
813 - this._enhancePromise(promise);  
814 - promise.abort = function () {  
815 - return jqXHR.abort();  
816 - };  
817 - upload();  
818 - return promise;  
819 - },  
820 -  
821 - _beforeSend: function (e, data) {  
822 - if (this._active === 0) {  
823 - // the start callback is triggered when an upload starts  
824 - // and no other uploads are currently running,  
825 - // equivalent to the global ajaxStart event:  
826 - this._trigger('start');  
827 - // Set timer for global bitrate progress calculation:  
828 - this._bitrateTimer = new this._BitrateTimer();  
829 - // Reset the global progress values:  
830 - this._progress.loaded = this._progress.total = 0;  
831 - this._progress.bitrate = 0;  
832 - }  
833 - // Make sure the container objects for the .response() and  
834 - // .progress() methods on the data object are available  
835 - // and reset to their initial state:  
836 - this._initResponseObject(data);  
837 - this._initProgressObject(data);  
838 - data._progress.loaded = data.loaded = data.uploadedBytes || 0;  
839 - data._progress.total = data.total = this._getTotal(data.files) || 1;  
840 - data._progress.bitrate = data.bitrate = 0;  
841 - this._active += 1;  
842 - // Initialize the global progress values:  
843 - this._progress.loaded += data.loaded;  
844 - this._progress.total += data.total;  
845 - },  
846 -  
847 - _onDone: function (result, textStatus, jqXHR, options) {  
848 - var total = options._progress.total,  
849 - response = options._response;  
850 - if (options._progress.loaded < total) {  
851 - // Create a progress event if no final progress event  
852 - // with loaded equaling total has been triggered:  
853 - this._onProgress($.Event('progress', {  
854 - lengthComputable: true,  
855 - loaded: total,  
856 - total: total  
857 - }), options);  
858 - }  
859 - response.result = options.result = result;  
860 - response.textStatus = options.textStatus = textStatus;  
861 - response.jqXHR = options.jqXHR = jqXHR;  
862 - this._trigger('done', null, options);  
863 - },  
864 -  
865 - _onFail: function (jqXHR, textStatus, errorThrown, options) {  
866 - var response = options._response;  
867 - if (options.recalculateProgress) {  
868 - // Remove the failed (error or abort) file upload from  
869 - // the global progress calculation:  
870 - this._progress.loaded -= options._progress.loaded;  
871 - this._progress.total -= options._progress.total;  
872 - }  
873 - response.jqXHR = options.jqXHR = jqXHR;  
874 - response.textStatus = options.textStatus = textStatus;  
875 - response.errorThrown = options.errorThrown = errorThrown;  
876 - this._trigger('fail', null, options);  
877 - },  
878 -  
879 - _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {  
880 - // jqXHRorResult, textStatus and jqXHRorError are added to the  
881 - // options object via done and fail callbacks  
882 - this._trigger('always', null, options);  
883 - },  
884 -  
885 - _onSend: function (e, data) {  
886 - if (!data.submit) {  
887 - this._addConvenienceMethods(e, data);  
888 - }  
889 - var that = this,  
890 - jqXHR,  
891 - aborted,  
892 - slot,  
893 - pipe,  
894 - options = that._getAJAXSettings(data),  
895 - send = function () {  
896 - that._sending += 1;  
897 - // Set timer for bitrate progress calculation:  
898 - options._bitrateTimer = new that._BitrateTimer();  
899 - jqXHR = jqXHR || (  
900 - ((aborted || that._trigger(  
901 - 'send',  
902 - $.Event('send', {delegatedEvent: e}),  
903 - options  
904 - ) === false) &&  
905 - that._getXHRPromise(false, options.context, aborted)) ||  
906 - that._chunkedUpload(options) || $.ajax(options)  
907 - ).done(function (result, textStatus, jqXHR) {  
908 - that._onDone(result, textStatus, jqXHR, options);  
909 - }).fail(function (jqXHR, textStatus, errorThrown) {  
910 - that._onFail(jqXHR, textStatus, errorThrown, options);  
911 - }).always(function (jqXHRorResult, textStatus, jqXHRorError) {  
912 - that._onAlways(  
913 - jqXHRorResult,  
914 - textStatus,  
915 - jqXHRorError,  
916 - options  
917 - );  
918 - that._sending -= 1;  
919 - that._active -= 1;  
920 - if (options.limitConcurrentUploads &&  
921 - options.limitConcurrentUploads > that._sending) {  
922 - // Start the next queued upload,  
923 - // that has not been aborted:  
924 - var nextSlot = that._slots.shift();  
925 - while (nextSlot) {  
926 - if (that._getDeferredState(nextSlot) === 'pending') {  
927 - nextSlot.resolve();  
928 - break;  
929 - }  
930 - nextSlot = that._slots.shift();  
931 - }  
932 - }  
933 - if (that._active === 0) {  
934 - // The stop callback is triggered when all uploads have  
935 - // been completed, equivalent to the global ajaxStop event:  
936 - that._trigger('stop');  
937 - }  
938 - });  
939 - return jqXHR;  
940 - };  
941 - this._beforeSend(e, options);  
942 - if (this.options.sequentialUploads ||  
943 - (this.options.limitConcurrentUploads &&  
944 - this.options.limitConcurrentUploads <= this._sending)) {  
945 - if (this.options.limitConcurrentUploads > 1) {  
946 - slot = $.Deferred();  
947 - this._slots.push(slot);  
948 - pipe = slot.pipe(send);  
949 - } else {  
950 - this._sequence = this._sequence.pipe(send, send);  
951 - pipe = this._sequence;  
952 - }  
953 - // Return the piped Promise object, enhanced with an abort method,  
954 - // which is delegated to the jqXHR object of the current upload,  
955 - // and jqXHR callbacks mapped to the equivalent Promise methods:  
956 - pipe.abort = function () {  
957 - aborted = [undefined, 'abort', 'abort'];  
958 - if (!jqXHR) {  
959 - if (slot) {  
960 - slot.rejectWith(options.context, aborted);  
961 - }  
962 - return send();  
963 - }  
964 - return jqXHR.abort();  
965 - };  
966 - return this._enhancePromise(pipe);  
967 - }  
968 - return send();  
969 - },  
970 -  
971 - _onAdd: function (e, data) {  
972 - var that = this,  
973 - result = true,  
974 - options = $.extend({}, this.options, data),  
975 - files = data.files,  
976 - filesLength = files.length,  
977 - limit = options.limitMultiFileUploads,  
978 - limitSize = options.limitMultiFileUploadSize,  
979 - overhead = options.limitMultiFileUploadSizeOverhead,  
980 - batchSize = 0,  
981 - paramName = this._getParamName(options),  
982 - paramNameSet,  
983 - paramNameSlice,  
984 - fileSet,  
985 - i,  
986 - j = 0;  
987 - if (!filesLength) {  
988 - return false;  
989 - }  
990 - if (limitSize && files[0].size === undefined) {  
991 - limitSize = undefined;  
992 - }  
993 - if (!(options.singleFileUploads || limit || limitSize) ||  
994 - !this._isXHRUpload(options)) {  
995 - fileSet = [files];  
996 - paramNameSet = [paramName];  
997 - } else if (!(options.singleFileUploads || limitSize) && limit) {  
998 - fileSet = [];  
999 - paramNameSet = [];  
1000 - for (i = 0; i < filesLength; i += limit) {  
1001 - fileSet.push(files.slice(i, i + limit));  
1002 - paramNameSlice = paramName.slice(i, i + limit);  
1003 - if (!paramNameSlice.length) {  
1004 - paramNameSlice = paramName;  
1005 - }  
1006 - paramNameSet.push(paramNameSlice);  
1007 - }  
1008 - } else if (!options.singleFileUploads && limitSize) {  
1009 - fileSet = [];  
1010 - paramNameSet = [];  
1011 - for (i = 0; i < filesLength; i = i + 1) {  
1012 - batchSize += files[i].size + overhead;  
1013 - if (i + 1 === filesLength ||  
1014 - ((batchSize + files[i + 1].size + overhead) > limitSize) ||  
1015 - (limit && i + 1 - j >= limit)) {  
1016 - fileSet.push(files.slice(j, i + 1));  
1017 - paramNameSlice = paramName.slice(j, i + 1);  
1018 - if (!paramNameSlice.length) {  
1019 - paramNameSlice = paramName;  
1020 - }  
1021 - paramNameSet.push(paramNameSlice);  
1022 - j = i + 1;  
1023 - batchSize = 0;  
1024 - }  
1025 - }  
1026 - } else {  
1027 - paramNameSet = paramName;  
1028 - }  
1029 - data.originalFiles = files;  
1030 - $.each(fileSet || files, function (index, element) {  
1031 - var newData = $.extend({}, data);  
1032 - newData.files = fileSet ? element : [element];  
1033 - newData.paramName = paramNameSet[index];  
1034 - that._initResponseObject(newData);  
1035 - that._initProgressObject(newData);  
1036 - that._addConvenienceMethods(e, newData);  
1037 - result = that._trigger(  
1038 - 'add',  
1039 - $.Event('add', {delegatedEvent: e}),  
1040 - newData  
1041 - );  
1042 - return result;  
1043 - });  
1044 - return result;  
1045 - },  
1046 -  
1047 - _replaceFileInput: function (data) {  
1048 - var input = data.fileInput,  
1049 - inputClone = input.clone(true),  
1050 - restoreFocus = input.is(document.activeElement);  
1051 - // Add a reference for the new cloned file input to the data argument:  
1052 - data.fileInputClone = inputClone;  
1053 - $('<form></form>').append(inputClone)[0].reset();  
1054 - // Detaching allows to insert the fileInput on another form  
1055 - // without loosing the file input value:  
1056 - input.after(inputClone).detach();  
1057 - // If the fileInput had focus before it was detached,  
1058 - // restore focus to the inputClone.  
1059 - if (restoreFocus) {  
1060 - inputClone.focus();  
1061 - }  
1062 - // Avoid memory leaks with the detached file input:  
1063 - $.cleanData(input.unbind('remove'));  
1064 - // Replace the original file input element in the fileInput  
1065 - // elements set with the clone, which has been copied including  
1066 - // event handlers:  
1067 - this.options.fileInput = this.options.fileInput.map(function (i, el) {  
1068 - if (el === input[0]) {  
1069 - return inputClone[0];  
1070 - }  
1071 - return el;  
1072 - });  
1073 - // If the widget has been initialized on the file input itself,  
1074 - // override this.element with the file input clone:  
1075 - if (input[0] === this.element[0]) {  
1076 - this.element = inputClone;  
1077 - }  
1078 - },  
1079 -  
1080 - _handleFileTreeEntry: function (entry, path) {  
1081 - var that = this,  
1082 - dfd = $.Deferred(),  
1083 - errorHandler = function (e) {  
1084 - if (e && !e.entry) {  
1085 - e.entry = entry;  
1086 - }  
1087 - // Since $.when returns immediately if one  
1088 - // Deferred is rejected, we use resolve instead.  
1089 - // This allows valid files and invalid items  
1090 - // to be returned together in one set:  
1091 - dfd.resolve([e]);  
1092 - },  
1093 - successHandler = function (entries) {  
1094 - that._handleFileTreeEntries(  
1095 - entries,  
1096 - path + entry.name + '/'  
1097 - ).done(function (files) {  
1098 - dfd.resolve(files);  
1099 - }).fail(errorHandler);  
1100 - },  
1101 - readEntries = function () {  
1102 - dirReader.readEntries(function (results) {  
1103 - if (!results.length) {  
1104 - successHandler(entries);  
1105 - } else {  
1106 - entries = entries.concat(results);  
1107 - readEntries();  
1108 - }  
1109 - }, errorHandler);  
1110 - },  
1111 - dirReader, entries = [];  
1112 - path = path || '';  
1113 - if (entry.isFile) {  
1114 - if (entry._file) {  
1115 - // Workaround for Chrome bug #149735  
1116 - entry._file.relativePath = path;  
1117 - dfd.resolve(entry._file);  
1118 - } else {  
1119 - entry.file(function (file) {  
1120 - file.relativePath = path;  
1121 - dfd.resolve(file);  
1122 - }, errorHandler);  
1123 - }  
1124 - } else if (entry.isDirectory) {  
1125 - dirReader = entry.createReader();  
1126 - readEntries();  
1127 - } else {  
1128 - // Return an empy list for file system items  
1129 - // other than files or directories:  
1130 - dfd.resolve([]);  
1131 - }  
1132 - return dfd.promise();  
1133 - },  
1134 -  
1135 - _handleFileTreeEntries: function (entries, path) {  
1136 - var that = this;  
1137 - return $.when.apply(  
1138 - $,  
1139 - $.map(entries, function (entry) {  
1140 - return that._handleFileTreeEntry(entry, path);  
1141 - })  
1142 - ).pipe(function () {  
1143 - return Array.prototype.concat.apply(  
1144 - [],  
1145 - arguments  
1146 - );  
1147 - });  
1148 - },  
1149 -  
1150 - _getDroppedFiles: function (dataTransfer) {  
1151 - dataTransfer = dataTransfer || {};  
1152 - var items = dataTransfer.items;  
1153 - if (items && items.length && (items[0].webkitGetAsEntry ||  
1154 - items[0].getAsEntry)) {  
1155 - return this._handleFileTreeEntries(  
1156 - $.map(items, function (item) {  
1157 - var entry;  
1158 - if (item.webkitGetAsEntry) {  
1159 - entry = item.webkitGetAsEntry();  
1160 - if (entry) {  
1161 - // Workaround for Chrome bug #149735:  
1162 - entry._file = item.getAsFile();  
1163 - }  
1164 - return entry;  
1165 - }  
1166 - return item.getAsEntry();  
1167 - })  
1168 - );  
1169 - }  
1170 - return $.Deferred().resolve(  
1171 - $.makeArray(dataTransfer.files)  
1172 - ).promise();  
1173 - },  
1174 -  
1175 - _getSingleFileInputFiles: function (fileInput) {  
1176 - fileInput = $(fileInput);  
1177 - var entries = fileInput.prop('webkitEntries') ||  
1178 - fileInput.prop('entries'),  
1179 - files,  
1180 - value;  
1181 - if (entries && entries.length) {  
1182 - return this._handleFileTreeEntries(entries);  
1183 - }  
1184 - files = $.makeArray(fileInput.prop('files'));  
1185 - if (!files.length) {  
1186 - value = fileInput.prop('value');  
1187 - if (!value) {  
1188 - return $.Deferred().resolve([]).promise();  
1189 - }  
1190 - // If the files property is not available, the browser does not  
1191 - // support the File API and we add a pseudo File object with  
1192 - // the input value as name with path information removed:  
1193 - files = [{name: value.replace(/^.*\\/, '')}];  
1194 - } else if (files[0].name === undefined && files[0].fileName) {  
1195 - // File normalization for Safari 4 and Firefox 3:  
1196 - $.each(files, function (index, file) {  
1197 - file.name = file.fileName;  
1198 - file.size = file.fileSize;  
1199 - });  
1200 - }  
1201 - return $.Deferred().resolve(files).promise();  
1202 - },  
1203 -  
1204 - _getFileInputFiles: function (fileInput) {  
1205 - if (!(fileInput instanceof $) || fileInput.length === 1) {  
1206 - return this._getSingleFileInputFiles(fileInput);  
1207 - }  
1208 - return $.when.apply(  
1209 - $,  
1210 - $.map(fileInput, this._getSingleFileInputFiles)  
1211 - ).pipe(function () {  
1212 - return Array.prototype.concat.apply(  
1213 - [],  
1214 - arguments  
1215 - );  
1216 - });  
1217 - },  
1218 -  
1219 - _onChange: function (e) {  
1220 - var that = this,  
1221 - data = {  
1222 - fileInput: $(e.target),  
1223 - form: $(e.target.form)  
1224 - };  
1225 - this._getFileInputFiles(data.fileInput).always(function (files) {  
1226 - data.files = files;  
1227 - if (that.options.replaceFileInput) {  
1228 - that._replaceFileInput(data);  
1229 - }  
1230 - if (that._trigger(  
1231 - 'change',  
1232 - $.Event('change', {delegatedEvent: e}),  
1233 - data  
1234 - ) !== false) {  
1235 - that._onAdd(e, data);  
1236 - }  
1237 - });  
1238 - },  
1239 -  
1240 - _onPaste: function (e) {  
1241 - var items = e.originalEvent && e.originalEvent.clipboardData &&  
1242 - e.originalEvent.clipboardData.items,  
1243 - data = {files: []};  
1244 - if (items && items.length) {  
1245 - $.each(items, function (index, item) {  
1246 - var file = item.getAsFile && item.getAsFile();  
1247 - if (file) {  
1248 - data.files.push(file);  
1249 - }  
1250 - });  
1251 - if (this._trigger(  
1252 - 'paste',  
1253 - $.Event('paste', {delegatedEvent: e}),  
1254 - data  
1255 - ) !== false) {  
1256 - this._onAdd(e, data);  
1257 - }  
1258 - }  
1259 - },  
1260 -  
1261 - _onDrop: function (e) {  
1262 - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;  
1263 - var that = this,  
1264 - dataTransfer = e.dataTransfer,  
1265 - data = {};  
1266 - if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {  
1267 - e.preventDefault();  
1268 - this._getDroppedFiles(dataTransfer).always(function (files) {  
1269 - data.files = files;  
1270 - if (that._trigger(  
1271 - 'drop',  
1272 - $.Event('drop', {delegatedEvent: e}),  
1273 - data  
1274 - ) !== false) {  
1275 - that._onAdd(e, data);  
1276 - }  
1277 - });  
1278 - }  
1279 - },  
1280 -  
1281 - _onDragOver: getDragHandler('dragover'),  
1282 -  
1283 - _onDragEnter: getDragHandler('dragenter'),  
1284 -  
1285 - _onDragLeave: getDragHandler('dragleave'),  
1286 -  
1287 - _initEventHandlers: function () {  
1288 - if (this._isXHRUpload(this.options)) {  
1289 - this._on(this.options.dropZone, {  
1290 - dragover: this._onDragOver,  
1291 - drop: this._onDrop,  
1292 - // event.preventDefault() on dragenter is required for IE10+:  
1293 - dragenter: this._onDragEnter,  
1294 - // dragleave is not required, but added for completeness:  
1295 - dragleave: this._onDragLeave  
1296 - });  
1297 - this._on(this.options.pasteZone, {  
1298 - paste: this._onPaste  
1299 - });  
1300 - }  
1301 - if ($.support.fileInput) {  
1302 - this._on(this.options.fileInput, {  
1303 - change: this._onChange  
1304 - });  
1305 - }  
1306 - },  
1307 -  
1308 - _destroyEventHandlers: function () {  
1309 - this._off(this.options.dropZone, 'dragenter dragleave dragover drop');  
1310 - this._off(this.options.pasteZone, 'paste');  
1311 - this._off(this.options.fileInput, 'change');  
1312 - },  
1313 -  
1314 - _setOption: function (key, value) {  
1315 - var reinit = $.inArray(key, this._specialOptions) !== -1;  
1316 - if (reinit) {  
1317 - this._destroyEventHandlers();  
1318 - }  
1319 - this._super(key, value);  
1320 - if (reinit) {  
1321 - this._initSpecialOptions();  
1322 - this._initEventHandlers();  
1323 - }  
1324 - },  
1325 -  
1326 - _initSpecialOptions: function () {  
1327 - var options = this.options;  
1328 - if (options.fileInput === undefined) {  
1329 - options.fileInput = this.element.is('input[type="file"]') ?  
1330 - this.element : this.element.find('input[type="file"]');  
1331 - } else if (!(options.fileInput instanceof $)) {  
1332 - options.fileInput = $(options.fileInput);  
1333 - }  
1334 - if (!(options.dropZone instanceof $)) {  
1335 - options.dropZone = $(options.dropZone);  
1336 - }  
1337 - if (!(options.pasteZone instanceof $)) {  
1338 - options.pasteZone = $(options.pasteZone);  
1339 - }  
1340 - },  
1341 -  
1342 - _getRegExp: function (str) {  
1343 - var parts = str.split('/'),  
1344 - modifiers = parts.pop();  
1345 - parts.shift();  
1346 - return new RegExp(parts.join('/'), modifiers);  
1347 - },  
1348 -  
1349 - _isRegExpOption: function (key, value) {  
1350 - return key !== 'url' && $.type(value) === 'string' &&  
1351 - /^\/.*\/[igm]{0,3}$/.test(value);  
1352 - },  
1353 -  
1354 - _initDataAttributes: function () {  
1355 - var that = this,  
1356 - options = this.options,  
1357 - data = this.element.data();  
1358 - // Initialize options set via HTML5 data-attributes:  
1359 - $.each(  
1360 - this.element[0].attributes,  
1361 - function (index, attr) {  
1362 - var key = attr.name.toLowerCase(),  
1363 - value;  
1364 - if (/^data-/.test(key)) {  
1365 - // Convert hyphen-ated key to camelCase:  
1366 - key = key.slice(5).replace(/-[a-z]/g, function (str) {  
1367 - return str.charAt(1).toUpperCase();  
1368 - });  
1369 - value = data[key];  
1370 - if (that._isRegExpOption(key, value)) {  
1371 - value = that._getRegExp(value);  
1372 - }  
1373 - options[key] = value;  
1374 - }  
1375 - }  
1376 - );  
1377 - },  
1378 -  
1379 - _create: function () {  
1380 - this._initDataAttributes();  
1381 - this._initSpecialOptions();  
1382 - this._slots = [];  
1383 - this._sequence = this._getXHRPromise(true);  
1384 - this._sending = this._active = 0;  
1385 - this._initProgressObject(this);  
1386 - this._initEventHandlers();  
1387 - },  
1388 -  
1389 - // This method is exposed to the widget API and allows to query  
1390 - // the number of active uploads:  
1391 - active: function () {  
1392 - return this._active;  
1393 - },  
1394 -  
1395 - // This method is exposed to the widget API and allows to query  
1396 - // the widget upload progress.  
1397 - // It returns an object with loaded, total and bitrate properties  
1398 - // for the running uploads:  
1399 - progress: function () {  
1400 - return this._progress;  
1401 - },  
1402 -  
1403 - // This method is exposed to the widget API and allows adding files  
1404 - // using the fileupload API. The data parameter accepts an object which  
1405 - // must have a files property and can contain additional options:  
1406 - // .fileupload('add', {files: filesList});  
1407 - add: function (data) {  
1408 - var that = this;  
1409 - if (!data || this.options.disabled) {  
1410 - return;  
1411 - }  
1412 - if (data.fileInput && !data.files) {  
1413 - this._getFileInputFiles(data.fileInput).always(function (files) {  
1414 - data.files = files;  
1415 - that._onAdd(null, data);  
1416 - });  
1417 - } else {  
1418 - data.files = $.makeArray(data.files);  
1419 - this._onAdd(null, data);  
1420 - }  
1421 - },  
1422 -  
1423 - // This method is exposed to the widget API and allows sending files  
1424 - // using the fileupload API. The data parameter accepts an object which  
1425 - // must have a files or fileInput property and can contain additional options:  
1426 - // .fileupload('send', {files: filesList});  
1427 - // The method returns a Promise object for the file upload call.  
1428 - send: function (data) {  
1429 - if (data && !this.options.disabled) {  
1430 - if (data.fileInput && !data.files) {  
1431 - var that = this,  
1432 - dfd = $.Deferred(),  
1433 - promise = dfd.promise(),  
1434 - jqXHR,  
1435 - aborted;  
1436 - promise.abort = function () {  
1437 - aborted = true;  
1438 - if (jqXHR) {  
1439 - return jqXHR.abort();  
1440 - }  
1441 - dfd.reject(null, 'abort', 'abort');  
1442 - return promise;  
1443 - };  
1444 - this._getFileInputFiles(data.fileInput).always(  
1445 - function (files) {  
1446 - if (aborted) {  
1447 - return;  
1448 - }  
1449 - if (!files.length) {  
1450 - dfd.reject();  
1451 - return;  
1452 - }  
1453 - data.files = files;  
1454 - jqXHR = that._onSend(null, data);  
1455 - jqXHR.then(  
1456 - function (result, textStatus, jqXHR) {  
1457 - dfd.resolve(result, textStatus, jqXHR);  
1458 - },  
1459 - function (jqXHR, textStatus, errorThrown) {  
1460 - dfd.reject(jqXHR, textStatus, errorThrown);  
1461 - }  
1462 - );  
1463 - }  
1464 - );  
1465 - return this._enhancePromise(promise);  
1466 - }  
1467 - data.files = $.makeArray(data.files);  
1468 - if (data.files.length) {  
1469 - return this._onSend(null, data);  
1470 - }  
1471 - }  
1472 - return this._getXHRPromise(false, data && data.context);  
1473 - }  
1474 -  
1475 - });  
1476 -  
1477 -}));  
artbox-file/assets/js/jquery.iframe-transport.js deleted
1 -/*  
2 - * jQuery Iframe Transport Plugin  
3 - * https://github.com/blueimp/jQuery-File-Upload  
4 - *  
5 - * Copyright 2011, Sebastian Tschan  
6 - * https://blueimp.net  
7 - *  
8 - * Licensed under the MIT license:  
9 - * http://www.opensource.org/licenses/MIT  
10 - */  
11 -  
12 -/* global define, require, window, document */  
13 -  
14 -(function (factory) {  
15 - 'use strict';  
16 - if (typeof define === 'function' && define.amd) {  
17 - // Register as an anonymous AMD module:  
18 - define(['jquery'], factory);  
19 - } else if (typeof exports === 'object') {  
20 - // Node/CommonJS:  
21 - factory(require('jquery'));  
22 - } else {  
23 - // Browser globals:  
24 - factory(window.jQuery);  
25 - }  
26 -}(function ($) {  
27 - 'use strict';  
28 -  
29 - // Helper variable to create unique names for the transport iframes:  
30 - var counter = 0;  
31 -  
32 - // The iframe transport accepts four additional options:  
33 - // options.fileInput: a jQuery collection of file input fields  
34 - // options.paramName: the parameter name for the file form data,  
35 - // overrides the name property of the file input field(s),  
36 - // can be a string or an array of strings.  
37 - // options.formData: an array of objects with name and value properties,  
38 - // equivalent to the return data of .serializeArray(), e.g.:  
39 - // [{name: 'a', value: 1}, {name: 'b', value: 2}]  
40 - // options.initialIframeSrc: the URL of the initial iframe src,  
41 - // by default set to "javascript:false;"  
42 - $.ajaxTransport('iframe', function (options) {  
43 - if (options.async) {  
44 - // javascript:false as initial iframe src  
45 - // prevents warning popups on HTTPS in IE6:  
46 - /*jshint scripturl: true */  
47 - var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',  
48 - /*jshint scripturl: false */  
49 - form,  
50 - iframe,  
51 - addParamChar;  
52 - return {  
53 - send: function (_, completeCallback) {  
54 - form = $('<form style="display:none;"></form>');  
55 - form.attr('accept-charset', options.formAcceptCharset);  
56 - addParamChar = /\?/.test(options.url) ? '&' : '?';  
57 - // XDomainRequest only supports GET and POST:  
58 - if (options.type === 'DELETE') {  
59 - options.url = options.url + addParamChar + '_method=DELETE';  
60 - options.type = 'POST';  
61 - } else if (options.type === 'PUT') {  
62 - options.url = options.url + addParamChar + '_method=PUT';  
63 - options.type = 'POST';  
64 - } else if (options.type === 'PATCH') {  
65 - options.url = options.url + addParamChar + '_method=PATCH';  
66 - options.type = 'POST';  
67 - }  
68 - // IE versions below IE8 cannot set the name property of  
69 - // elements that have already been added to the DOM,  
70 - // so we set the name along with the iframe HTML markup:  
71 - counter += 1;  
72 - iframe = $(  
73 - '<iframe src="' + initialIframeSrc +  
74 - '" name="iframe-transport-' + counter + '"></iframe>'  
75 - ).bind('load', function () {  
76 - var fileInputClones,  
77 - paramNames = $.isArray(options.paramName) ?  
78 - options.paramName : [options.paramName];  
79 - iframe  
80 - .unbind('load')  
81 - .bind('load', function () {  
82 - var response;  
83 - // Wrap in a try/catch block to catch exceptions thrown  
84 - // when trying to access cross-domain iframe contents:  
85 - try {  
86 - response = iframe.contents();  
87 - // Google Chrome and Firefox do not throw an  
88 - // exception when calling iframe.contents() on  
89 - // cross-domain requests, so we unify the response:  
90 - if (!response.length || !response[0].firstChild) {  
91 - throw new Error();  
92 - }  
93 - } catch (e) {  
94 - response = undefined;  
95 - }  
96 - // The complete callback returns the  
97 - // iframe content document as response object:  
98 - completeCallback(  
99 - 200,  
100 - 'success',  
101 - {'iframe': response}  
102 - );  
103 - // Fix for IE endless progress bar activity bug  
104 - // (happens on form submits to iframe targets):  
105 - $('<iframe src="' + initialIframeSrc + '"></iframe>')  
106 - .appendTo(form);  
107 - window.setTimeout(function () {  
108 - // Removing the form in a setTimeout call  
109 - // allows Chrome's developer tools to display  
110 - // the response result  
111 - form.remove();  
112 - }, 0);  
113 - });  
114 - form  
115 - .prop('target', iframe.prop('name'))  
116 - .prop('action', options.url)  
117 - .prop('method', options.type);  
118 - if (options.formData) {  
119 - $.each(options.formData, function (index, field) {  
120 - $('<input type="hidden"/>')  
121 - .prop('name', field.name)  
122 - .val(field.value)  
123 - .appendTo(form);  
124 - });  
125 - }  
126 - if (options.fileInput && options.fileInput.length &&  
127 - options.type === 'POST') {  
128 - fileInputClones = options.fileInput.clone();  
129 - // Insert a clone for each file input field:  
130 - options.fileInput.after(function (index) {  
131 - return fileInputClones[index];  
132 - });  
133 - if (options.paramName) {  
134 - options.fileInput.each(function (index) {  
135 - $(this).prop(  
136 - 'name',  
137 - paramNames[index] || options.paramName  
138 - );  
139 - });  
140 - }  
141 - // Appending the file input fields to the hidden form  
142 - // removes them from their original location:  
143 - form  
144 - .append(options.fileInput)  
145 - .prop('enctype', 'multipart/form-data')  
146 - // enctype must be set as encoding for IE:  
147 - .prop('encoding', 'multipart/form-data');  
148 - // Remove the HTML5 form attribute from the input(s):  
149 - options.fileInput.removeAttr('form');  
150 - }  
151 - form.submit();  
152 - // Insert the file input fields at their original location  
153 - // by replacing the clones with the originals:  
154 - if (fileInputClones && fileInputClones.length) {  
155 - options.fileInput.each(function (index, input) {  
156 - var clone = $(fileInputClones[index]);  
157 - // Restore the original name and form properties:  
158 - $(input)  
159 - .prop('name', clone.prop('name'))  
160 - .attr('form', clone.attr('form'));  
161 - clone.replaceWith(input);  
162 - });  
163 - }  
164 - });  
165 - form.append(iframe).appendTo(document.body);  
166 - },  
167 - abort: function () {  
168 - if (iframe) {  
169 - // javascript:false as iframe src aborts the request  
170 - // and prevents warning popups on HTTPS in IE6.  
171 - // concat is used to avoid the "Script URL" JSLint error:  
172 - iframe  
173 - .unbind('load')  
174 - .prop('src', initialIframeSrc);  
175 - }  
176 - if (form) {  
177 - form.remove();  
178 - }  
179 - }  
180 - };  
181 - }  
182 - });  
183 -  
184 - // The iframe transport returns the iframe content document as response.  
185 - // The following adds converters from iframe to text, json, html, xml  
186 - // and script.  
187 - // Please note that the Content-Type for JSON responses has to be text/plain  
188 - // or text/html, if the browser doesn't include application/json in the  
189 - // Accept header, else IE will show a download dialog.  
190 - // The Content-Type for XML responses on the other hand has to be always  
191 - // application/xml or text/xml, so IE properly parses the XML response.  
192 - // See also  
193 - // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation  
194 - $.ajaxSetup({  
195 - converters: {  
196 - 'iframe text': function (iframe) {  
197 - return iframe && $(iframe[0].body).text();  
198 - },  
199 - 'iframe json': function (iframe) {  
200 - return iframe && $.parseJSON($(iframe[0].body).text());  
201 - },  
202 - 'iframe html': function (iframe) {  
203 - return iframe && $(iframe[0].body).html();  
204 - },  
205 - 'iframe xml': function (iframe) {  
206 - var xmlDoc = iframe && iframe[0];  
207 - return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :  
208 - $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||  
209 - $(xmlDoc.body).html());  
210 - },  
211 - 'iframe script': function (iframe) {  
212 - return iframe && $.globalEval($(iframe[0].body).text());  
213 - }  
214 - }  
215 - });  
216 -  
217 -}));  
artbox-file/assets/js/vendor/jquery.ui.widget.js deleted
1 -/*! jQuery UI - v1.11.4+CommonJS - 2015-08-28  
2 -* http://jqueryui.com  
3 -* Includes: widget.js  
4 -* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */  
5 -  
6 -(function( factory ) {  
7 - if ( typeof define === "function" && define.amd ) {  
8 -  
9 - // AMD. Register as an anonymous module.  
10 - define([ "jquery" ], factory );  
11 -  
12 - } else if ( typeof exports === "object" ) {  
13 -  
14 - // Node/CommonJS  
15 - factory( require( "jquery" ) );  
16 -  
17 - } else {  
18 -  
19 - // Browser globals  
20 - factory( jQuery );  
21 - }  
22 -}(function( $ ) {  
23 -/*!  
24 - * jQuery UI Widget 1.11.4  
25 - * http://jqueryui.com  
26 - *  
27 - * Copyright jQuery Foundation and other contributors  
28 - * Released under the MIT license.  
29 - * http://jquery.org/license  
30 - *  
31 - * http://api.jqueryui.com/jQuery.widget/  
32 - */  
33 -  
34 -  
35 -var widget_uuid = 0,  
36 - widget_slice = Array.prototype.slice;  
37 -  
38 -$.cleanData = (function( orig ) {  
39 - return function( elems ) {  
40 - var events, elem, i;  
41 - for ( i = 0; (elem = elems[i]) != null; i++ ) {  
42 - try {  
43 -  
44 - // Only trigger remove when necessary to save time  
45 - events = $._data( elem, "events" );  
46 - if ( events && events.remove ) {  
47 - $( elem ).triggerHandler( "remove" );  
48 - }  
49 -  
50 - // http://bugs.jquery.com/ticket/8235  
51 - } catch ( e ) {}  
52 - }  
53 - orig( elems );  
54 - };  
55 -})( $.cleanData );  
56 -  
57 -$.widget = function( name, base, prototype ) {  
58 - var fullName, existingConstructor, constructor, basePrototype,  
59 - // proxiedPrototype allows the provided prototype to remain unmodified  
60 - // so that it can be used as a mixin for multiple widgets (#8876)  
61 - proxiedPrototype = {},  
62 - namespace = name.split( "." )[ 0 ];  
63 -  
64 - name = name.split( "." )[ 1 ];  
65 - fullName = namespace + "-" + name;  
66 -  
67 - if ( !prototype ) {  
68 - prototype = base;  
69 - base = $.Widget;  
70 - }  
71 -  
72 - // create selector for plugin  
73 - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {  
74 - return !!$.data( elem, fullName );  
75 - };  
76 -  
77 - $[ namespace ] = $[ namespace ] || {};  
78 - existingConstructor = $[ namespace ][ name ];  
79 - constructor = $[ namespace ][ name ] = function( options, element ) {  
80 - // allow instantiation without "new" keyword  
81 - if ( !this._createWidget ) {  
82 - return new constructor( options, element );  
83 - }  
84 -  
85 - // allow instantiation without initializing for simple inheritance  
86 - // must use "new" keyword (the code above always passes args)  
87 - if ( arguments.length ) {  
88 - this._createWidget( options, element );  
89 - }  
90 - };  
91 - // extend with the existing constructor to carry over any static properties  
92 - $.extend( constructor, existingConstructor, {  
93 - version: prototype.version,  
94 - // copy the object used to create the prototype in case we need to  
95 - // redefine the widget later  
96 - _proto: $.extend( {}, prototype ),  
97 - // track widgets that inherit from this widget in case this widget is  
98 - // redefined after a widget inherits from it  
99 - _childConstructors: []  
100 - });  
101 -  
102 - basePrototype = new base();  
103 - // we need to make the options hash a property directly on the new instance  
104 - // otherwise we'll modify the options hash on the prototype that we're  
105 - // inheriting from  
106 - basePrototype.options = $.widget.extend( {}, basePrototype.options );  
107 - $.each( prototype, function( prop, value ) {  
108 - if ( !$.isFunction( value ) ) {  
109 - proxiedPrototype[ prop ] = value;  
110 - return;  
111 - }  
112 - proxiedPrototype[ prop ] = (function() {  
113 - var _super = function() {  
114 - return base.prototype[ prop ].apply( this, arguments );  
115 - },  
116 - _superApply = function( args ) {  
117 - return base.prototype[ prop ].apply( this, args );  
118 - };  
119 - return function() {  
120 - var __super = this._super,  
121 - __superApply = this._superApply,  
122 - returnValue;  
123 -  
124 - this._super = _super;  
125 - this._superApply = _superApply;  
126 -  
127 - returnValue = value.apply( this, arguments );  
128 -  
129 - this._super = __super;  
130 - this._superApply = __superApply;  
131 -  
132 - return returnValue;  
133 - };  
134 - })();  
135 - });  
136 - constructor.prototype = $.widget.extend( basePrototype, {  
137 - // TODO: remove support for widgetEventPrefix  
138 - // always use the name + a colon as the prefix, e.g., draggable:start  
139 - // don't prefix for widgets that aren't DOM-based  
140 - widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name  
141 - }, proxiedPrototype, {  
142 - constructor: constructor,  
143 - namespace: namespace,  
144 - widgetName: name,  
145 - widgetFullName: fullName  
146 - });  
147 -  
148 - // If this widget is being redefined then we need to find all widgets that  
149 - // are inheriting from it and redefine all of them so that they inherit from  
150 - // the new version of this widget. We're essentially trying to replace one  
151 - // level in the prototype chain.  
152 - if ( existingConstructor ) {  
153 - $.each( existingConstructor._childConstructors, function( i, child ) {  
154 - var childPrototype = child.prototype;  
155 -  
156 - // redefine the child widget using the same prototype that was  
157 - // originally used, but inherit from the new version of the base  
158 - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );  
159 - });  
160 - // remove the list of existing child constructors from the old constructor  
161 - // so the old child constructors can be garbage collected  
162 - delete existingConstructor._childConstructors;  
163 - } else {  
164 - base._childConstructors.push( constructor );  
165 - }  
166 -  
167 - $.widget.bridge( name, constructor );  
168 -  
169 - return constructor;  
170 -};  
171 -  
172 -$.widget.extend = function( target ) {  
173 - var input = widget_slice.call( arguments, 1 ),  
174 - inputIndex = 0,  
175 - inputLength = input.length,  
176 - key,  
177 - value;  
178 - for ( ; inputIndex < inputLength; inputIndex++ ) {  
179 - for ( key in input[ inputIndex ] ) {  
180 - value = input[ inputIndex ][ key ];  
181 - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {  
182 - // Clone objects  
183 - if ( $.isPlainObject( value ) ) {  
184 - target[ key ] = $.isPlainObject( target[ key ] ) ?  
185 - $.widget.extend( {}, target[ key ], value ) :  
186 - // Don't extend strings, arrays, etc. with objects  
187 - $.widget.extend( {}, value );  
188 - // Copy everything else by reference  
189 - } else {  
190 - target[ key ] = value;  
191 - }  
192 - }  
193 - }  
194 - }  
195 - return target;  
196 -};  
197 -  
198 -$.widget.bridge = function( name, object ) {  
199 - var fullName = object.prototype.widgetFullName || name;  
200 - $.fn[ name ] = function( options ) {  
201 - var isMethodCall = typeof options === "string",  
202 - args = widget_slice.call( arguments, 1 ),  
203 - returnValue = this;  
204 -  
205 - if ( isMethodCall ) {  
206 - this.each(function() {  
207 - var methodValue,  
208 - instance = $.data( this, fullName );  
209 - if ( options === "instance" ) {  
210 - returnValue = instance;  
211 - return false;  
212 - }  
213 - if ( !instance ) {  
214 - return $.error( "cannot call methods on " + name + " prior to initialization; " +  
215 - "attempted to call method '" + options + "'" );  
216 - }  
217 - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {  
218 - return $.error( "no such method '" + options + "' for " + name + " widget instance" );  
219 - }  
220 - methodValue = instance[ options ].apply( instance, args );  
221 - if ( methodValue !== instance && methodValue !== undefined ) {  
222 - returnValue = methodValue && methodValue.jquery ?  
223 - returnValue.pushStack( methodValue.get() ) :  
224 - methodValue;  
225 - return false;  
226 - }  
227 - });  
228 - } else {  
229 -  
230 - // Allow multiple hashes to be passed on init  
231 - if ( args.length ) {  
232 - options = $.widget.extend.apply( null, [ options ].concat(args) );  
233 - }  
234 -  
235 - this.each(function() {  
236 - var instance = $.data( this, fullName );  
237 - if ( instance ) {  
238 - instance.option( options || {} );  
239 - if ( instance._init ) {  
240 - instance._init();  
241 - }  
242 - } else {  
243 - $.data( this, fullName, new object( options, this ) );  
244 - }  
245 - });  
246 - }  
247 -  
248 - return returnValue;  
249 - };  
250 -};  
251 -  
252 -$.Widget = function( /* options, element */ ) {};  
253 -$.Widget._childConstructors = [];  
254 -  
255 -$.Widget.prototype = {  
256 - widgetName: "widget",  
257 - widgetEventPrefix: "",  
258 - defaultElement: "<div>",  
259 - options: {  
260 - disabled: false,  
261 -  
262 - // callbacks  
263 - create: null  
264 - },  
265 - _createWidget: function( options, element ) {  
266 - element = $( element || this.defaultElement || this )[ 0 ];  
267 - this.element = $( element );  
268 - this.uuid = widget_uuid++;  
269 - this.eventNamespace = "." + this.widgetName + this.uuid;  
270 -  
271 - this.bindings = $();  
272 - this.hoverable = $();  
273 - this.focusable = $();  
274 -  
275 - if ( element !== this ) {  
276 - $.data( element, this.widgetFullName, this );  
277 - this._on( true, this.element, {  
278 - remove: function( event ) {  
279 - if ( event.target === element ) {  
280 - this.destroy();  
281 - }  
282 - }  
283 - });  
284 - this.document = $( element.style ?  
285 - // element within the document  
286 - element.ownerDocument :  
287 - // element is window or document  
288 - element.document || element );  
289 - this.window = $( this.document[0].defaultView || this.document[0].parentWindow );  
290 - }  
291 -  
292 - this.options = $.widget.extend( {},  
293 - this.options,  
294 - this._getCreateOptions(),  
295 - options );  
296 -  
297 - this._create();  
298 - this._trigger( "create", null, this._getCreateEventData() );  
299 - this._init();  
300 - },  
301 - _getCreateOptions: $.noop,  
302 - _getCreateEventData: $.noop,  
303 - _create: $.noop,  
304 - _init: $.noop,  
305 -  
306 - destroy: function() {  
307 - this._destroy();  
308 - // we can probably remove the unbind calls in 2.0  
309 - // all event bindings should go through this._on()  
310 - this.element  
311 - .unbind( this.eventNamespace )  
312 - .removeData( this.widgetFullName )  
313 - // support: jquery <1.6.3  
314 - // http://bugs.jquery.com/ticket/9413  
315 - .removeData( $.camelCase( this.widgetFullName ) );  
316 - this.widget()  
317 - .unbind( this.eventNamespace )  
318 - .removeAttr( "aria-disabled" )  
319 - .removeClass(  
320 - this.widgetFullName + "-disabled " +  
321 - "ui-state-disabled" );  
322 -  
323 - // clean up events and states  
324 - this.bindings.unbind( this.eventNamespace );  
325 - this.hoverable.removeClass( "ui-state-hover" );  
326 - this.focusable.removeClass( "ui-state-focus" );  
327 - },  
328 - _destroy: $.noop,  
329 -  
330 - widget: function() {  
331 - return this.element;  
332 - },  
333 -  
334 - option: function( key, value ) {  
335 - var options = key,  
336 - parts,  
337 - curOption,  
338 - i;  
339 -  
340 - if ( arguments.length === 0 ) {  
341 - // don't return a reference to the internal hash  
342 - return $.widget.extend( {}, this.options );  
343 - }  
344 -  
345 - if ( typeof key === "string" ) {  
346 - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }  
347 - options = {};  
348 - parts = key.split( "." );  
349 - key = parts.shift();  
350 - if ( parts.length ) {  
351 - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );  
352 - for ( i = 0; i < parts.length - 1; i++ ) {  
353 - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};  
354 - curOption = curOption[ parts[ i ] ];  
355 - }  
356 - key = parts.pop();  
357 - if ( arguments.length === 1 ) {  
358 - return curOption[ key ] === undefined ? null : curOption[ key ];  
359 - }  
360 - curOption[ key ] = value;  
361 - } else {  
362 - if ( arguments.length === 1 ) {  
363 - return this.options[ key ] === undefined ? null : this.options[ key ];  
364 - }  
365 - options[ key ] = value;  
366 - }  
367 - }  
368 -  
369 - this._setOptions( options );  
370 -  
371 - return this;  
372 - },  
373 - _setOptions: function( options ) {  
374 - var key;  
375 -  
376 - for ( key in options ) {  
377 - this._setOption( key, options[ key ] );  
378 - }  
379 -  
380 - return this;  
381 - },  
382 - _setOption: function( key, value ) {  
383 - this.options[ key ] = value;  
384 -  
385 - if ( key === "disabled" ) {  
386 - this.widget()  
387 - .toggleClass( this.widgetFullName + "-disabled", !!value );  
388 -  
389 - // If the widget is becoming disabled, then nothing is interactive  
390 - if ( value ) {  
391 - this.hoverable.removeClass( "ui-state-hover" );  
392 - this.focusable.removeClass( "ui-state-focus" );  
393 - }  
394 - }  
395 -  
396 - return this;  
397 - },  
398 -  
399 - enable: function() {  
400 - return this._setOptions({ disabled: false });  
401 - },  
402 - disable: function() {  
403 - return this._setOptions({ disabled: true });  
404 - },  
405 -  
406 - _on: function( suppressDisabledCheck, element, handlers ) {  
407 - var delegateElement,  
408 - instance = this;  
409 -  
410 - // no suppressDisabledCheck flag, shuffle arguments  
411 - if ( typeof suppressDisabledCheck !== "boolean" ) {  
412 - handlers = element;  
413 - element = suppressDisabledCheck;  
414 - suppressDisabledCheck = false;  
415 - }  
416 -  
417 - // no element argument, shuffle and use this.element  
418 - if ( !handlers ) {  
419 - handlers = element;  
420 - element = this.element;  
421 - delegateElement = this.widget();  
422 - } else {  
423 - element = delegateElement = $( element );  
424 - this.bindings = this.bindings.add( element );  
425 - }  
426 -  
427 - $.each( handlers, function( event, handler ) {  
428 - function handlerProxy() {  
429 - // allow widgets to customize the disabled handling  
430 - // - disabled as an array instead of boolean  
431 - // - disabled class as method for disabling individual parts  
432 - if ( !suppressDisabledCheck &&  
433 - ( instance.options.disabled === true ||  
434 - $( this ).hasClass( "ui-state-disabled" ) ) ) {  
435 - return;  
436 - }  
437 - return ( typeof handler === "string" ? instance[ handler ] : handler )  
438 - .apply( instance, arguments );  
439 - }  
440 -  
441 - // copy the guid so direct unbinding works  
442 - if ( typeof handler !== "string" ) {  
443 - handlerProxy.guid = handler.guid =  
444 - handler.guid || handlerProxy.guid || $.guid++;  
445 - }  
446 -  
447 - var match = event.match( /^([\w:-]*)\s*(.*)$/ ),  
448 - eventName = match[1] + instance.eventNamespace,  
449 - selector = match[2];  
450 - if ( selector ) {  
451 - delegateElement.delegate( selector, eventName, handlerProxy );  
452 - } else {  
453 - element.bind( eventName, handlerProxy );  
454 - }  
455 - });  
456 - },  
457 -  
458 - _off: function( element, eventName ) {  
459 - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +  
460 - this.eventNamespace;  
461 - element.unbind( eventName ).undelegate( eventName );  
462 -  
463 - // Clear the stack to avoid memory leaks (#10056)  
464 - this.bindings = $( this.bindings.not( element ).get() );  
465 - this.focusable = $( this.focusable.not( element ).get() );  
466 - this.hoverable = $( this.hoverable.not( element ).get() );  
467 - },  
468 -  
469 - _delay: function( handler, delay ) {  
470 - function handlerProxy() {  
471 - return ( typeof handler === "string" ? instance[ handler ] : handler )  
472 - .apply( instance, arguments );  
473 - }  
474 - var instance = this;  
475 - return setTimeout( handlerProxy, delay || 0 );  
476 - },  
477 -  
478 - _hoverable: function( element ) {  
479 - this.hoverable = this.hoverable.add( element );  
480 - this._on( element, {  
481 - mouseenter: function( event ) {  
482 - $( event.currentTarget ).addClass( "ui-state-hover" );  
483 - },  
484 - mouseleave: function( event ) {  
485 - $( event.currentTarget ).removeClass( "ui-state-hover" );  
486 - }  
487 - });  
488 - },  
489 -  
490 - _focusable: function( element ) {  
491 - this.focusable = this.focusable.add( element );  
492 - this._on( element, {  
493 - focusin: function( event ) {  
494 - $( event.currentTarget ).addClass( "ui-state-focus" );  
495 - },  
496 - focusout: function( event ) {  
497 - $( event.currentTarget ).removeClass( "ui-state-focus" );  
498 - }  
499 - });  
500 - },  
501 -  
502 - _trigger: function( type, event, data ) {  
503 - var prop, orig,  
504 - callback = this.options[ type ];  
505 -  
506 - data = data || {};  
507 - event = $.Event( event );  
508 - event.type = ( type === this.widgetEventPrefix ?  
509 - type :  
510 - this.widgetEventPrefix + type ).toLowerCase();  
511 - // the original event may come from any element  
512 - // so we need to reset the target on the new event  
513 - event.target = this.element[ 0 ];  
514 -  
515 - // copy original event properties over to the new event  
516 - orig = event.originalEvent;  
517 - if ( orig ) {  
518 - for ( prop in orig ) {  
519 - if ( !( prop in event ) ) {  
520 - event[ prop ] = orig[ prop ];  
521 - }  
522 - }  
523 - }  
524 -  
525 - this.element.trigger( event, data );  
526 - return !( $.isFunction( callback ) &&  
527 - callback.apply( this.element[0], [ event ].concat( data ) ) === false ||  
528 - event.isDefaultPrevented() );  
529 - }  
530 -};  
531 -  
532 -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {  
533 - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {  
534 - if ( typeof options === "string" ) {  
535 - options = { effect: options };  
536 - }  
537 - var hasOptions,  
538 - effectName = !options ?  
539 - method :  
540 - options === true || typeof options === "number" ?  
541 - defaultEffect :  
542 - options.effect || defaultEffect;  
543 - options = options || {};  
544 - if ( typeof options === "number" ) {  
545 - options = { duration: options };  
546 - }  
547 - hasOptions = !$.isEmptyObject( options );  
548 - options.complete = callback;  
549 - if ( options.delay ) {  
550 - element.delay( options.delay );  
551 - }  
552 - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {  
553 - element[ method ]( options );  
554 - } else if ( effectName !== method && element[ effectName ] ) {  
555 - element[ effectName ]( options.duration, options.easing, callback );  
556 - } else {  
557 - element.queue(function( next ) {  
558 - $( this )[ method ]();  
559 - if ( callback ) {  
560 - callback.call( element[ 0 ] );  
561 - }  
562 - next();  
563 - });  
564 - }  
565 - };  
566 -});  
567 -  
568 -var widget = $.widget;  
569 -  
570 -  
571 -  
572 -}));  
artbox-file/composer.json deleted
1 -{  
2 - "name": "artweb/artbox-file",  
3 - "description": "Yii2 light-weight CMS",  
4 - "license": "BSD-3-Clause",  
5 - "require": {  
6 - "php": ">=7.0",  
7 - "yiisoft/yii2": "*",  
8 - "developeruz/yii2-db-rbac": "*"  
9 - },  
10 - "autoload": {  
11 - "psr-4": {  
12 - "artweb\\artbox\\flie\\": ""  
13 - }  
14 - }  
15 -}  
16 \ No newline at end of file 0 \ No newline at end of file
artbox-file/config.php deleted
1 -<?php  
2 -return [  
3 -];  
artbox-file/controllers/UploaderController.php deleted
1 -<?php  
2 -/**  
3 - * Created by PhpStorm.  
4 - * User: Cibermag  
5 - * Date: 31.08.2015  
6 - * Time: 9:58  
7 - */  
8 -namespace artweb\artbox\file\controllers;  
9 -use Yii;  
10 -use yii\helpers\ArrayHelper;  
11 -use yii\web\UploadedFile;  
12 -use artweb\artbox\file\models\ImageSizerForm;  
13 -use yii\web\Controller;  
14 -use Imagine\Gd\Imagine;  
15 -use Imagine\Image\Box;  
16 -use yii\imagine\Image;  
17 -  
18 -class UploaderController extends Controller {  
19 -  
20 - public $enableCsrfValidation = false;  
21 -  
22 - public function isBigger($width,$height,$w,$h)  
23 - {  
24 - if($width>$w){  
25 - return true;  
26 - }else if($height >$h) {  
27 - return true;  
28 - }  
29 - return false;  
30 - }  
31 -  
32 -  
33 - private function getUserPath(){  
34 - if(isset(Yii::$app->user->id)){  
35 - return 'user_'.Yii::$app->user->id;  
36 - }else {  
37 - return 'guest';  
38 - }  
39 - }  
40 -  
41 - private function resizeImg($w, $h, $imageAlias,$imageAliasSave){  
42 - $img = Image::getImagine()->open(Yii::getAlias($imageAlias));  
43 -  
44 - $size = $img->getSize();  
45 -  
46 - $width = $size->getWidth();  
47 - $height = $size->getHeight();  
48 -  
49 - $e_width = $w/$h;  
50 - $e_height = $h/$w;  
51 -  
52 - $e1_width = $width/$height;  
53 - $e1_height = $height/$width;  
54 -  
55 -  
56 -  
57 - if($e_width<$e1_width){  
58 -  
59 - $new_width = $width*($e_width/$e1_width);  
60 -  
61 - $y = 0;  
62 - $x = $width/ 2-($new_width/2);  
63 - $width = $new_width;  
64 -  
65 - }else {  
66 -  
67 - $new_height = $height*($e_height/$e1_height);  
68 - $x = 0;  
69 - $y = $height/2-($new_height/2);  
70 - $height = $new_height;  
71 - }  
72 -  
73 -  
74 -  
75 -  
76 - Image::crop($imageAlias, $width, $height,[$x,$y])  
77 - ->save(Yii::getAlias($imageAliasSave), ['quality' =>  
78 - 100]);  
79 -  
80 -  
81 - $imagine = new Imagine();  
82 - $imagine->open($imageAliasSave)  
83 - ->resize(new Box($w, $h))  
84 - ->save($imageAliasSave, array('flatten' => false));  
85 -  
86 -  
87 -  
88 - }  
89 -  
90 - private function deleteImages($old_img){  
91 -  
92 - if(!empty($old_img) && file_exists($_SERVER['DOCUMENT_ROOT'].$old_img)){  
93 -  
94 - $rootDir = explode("/", $old_img);  
95 -  
96 - $row = $_SERVER['DOCUMENT_ROOT'].'/'.$rootDir[1].'/'.$rootDir[2].'/'.$rootDir[3].'/';  
97 -  
98 - $allFiles = scandir($row);  
99 -  
100 - $allFiles = array_slice($allFiles, 2);  
101 -  
102 - foreach($allFiles as $oldFile){  
103 -  
104 - unlink($row.$oldFile);  
105 -  
106 - }  
107 -  
108 - }  
109 - }  
110 -  
111 - public function actionDeleteImage(){  
112 -  
113 - $this->enableCsrfValidation = false;  
114 -  
115 - $request = Yii::$app->request->post();  
116 -  
117 - if($request){  
118 - if ($request['old_img']) {  
119 - $this->deleteImages($request['old_img']);  
120 - }  
121 - if(isset($request['action']) && $request['action']=='save'){  
122 - $object = str_replace('-', '\\',$request['model']);  
123 - $model = new $object;  
124 - $model = $model->findOne($request['id']);  
125 - $model->$request['field'] = $request['new_url'];  
126 - $model->save();  
127 - }  
128 - }  
129 -  
130 - }  
131 -  
132 -  
133 - public function actionDownloadPhoto()  
134 - {  
135 -  
136 - $model = new ImageSizerForm();  
137 -  
138 - $request = Yii::$app->request->post();  
139 -  
140 - if ($request) {  
141 -  
142 - $model->multi = isset($request['multi'])? 1 : 0;  
143 -  
144 - $model->file = UploadedFile::getInstance($model, 'file');  
145 -  
146 - $md5_file = md5_file($model->file->tempName).rand(1, 1000);  
147 -  
148 - $imgDir = Yii::getAlias('@storage/'.$this->getUserPath().'/'.$md5_file.'/');  
149 -  
150 - $imageOrigAlias = Yii::getAlias($imgDir.'original'.'.'.$model->file->extension);  
151 -  
152 - if(!is_dir($imgDir)) {  
153 - mkdir($imgDir, 0755, true);  
154 - }  
155 -  
156 - $model->file->saveAs($imageOrigAlias);  
157 -  
158 -  
159 - if(isset($request['size'] )){  
160 -  
161 - $request['size'] = ArrayHelper::toArray(json_decode($request['size']));  
162 -  
163 - foreach($request['size'] as $size){  
164 - if($size['width'] && $size['height']){  
165 -  
166 - $imageAlias = Yii::getAlias($imgDir.$size['width'].'x'.$size['height'].'.'.$model->file->extension);  
167 -  
168 - $imageLink = '/storage/'.$this->getUserPath().'/'.$md5_file.'/'.$size['width'].'x'.$size['height'].'.'.$model->file->extension;  
169 -  
170 - $this->resizeImg($size['width'], $size['height'], $imageOrigAlias,$imageAlias);  
171 -  
172 - }  
173 - }  
174 -  
175 - } else {  
176 -  
177 - $imageLink = '/storage/'.$this->getUserPath().'/'.$md5_file.'/'.'original'.'.'.$model->file->extension;  
178 -  
179 - }  
180 -  
181 -  
182 - if($model->multi){  
183 - $view = $this->renderPartial('/_gallery_item', [  
184 - 'item' => ['image'=>$imageLink],  
185 - 'field'=>$request['field']  
186 - ]);  
187 - return json_encode(['link'=>$imageLink,  
188 - 'view' =>$view,  
189 -  
190 - ]);  
191 -  
192 -  
193 - } else {  
194 - $view = $this->renderPartial('/_one_item', [  
195 - 'item' => ['image'=>$imageLink],  
196 - 'field'=>$request['field']  
197 - ]);  
198 - return json_encode(['link'=>$imageLink,  
199 - 'view' =>$view,  
200 - ]);  
201 - }  
202 -  
203 -  
204 - }  
205 - }  
206 -  
207 -  
208 - public function getex($filename) {  
209 - $array = explode(".", $filename);  
210 - return array_pop($array);  
211 - }  
212 -  
213 -  
214 - public function actionImagesUpload(){  
215 -  
216 - if($_FILES['upload'])  
217 - {  
218 - if (($_FILES['upload'] == "none") OR (empty($_FILES['upload']['name'])) )  
219 - {  
220 - $message = "ะ’ั‹ ะฝะต ะฒั‹ะฑั€ะฐะปะธ ั„ะฐะนะป";  
221 - }  
222 - else if ($_FILES['upload']["size"] == 0 OR $_FILES['upload']["size"] > 2050000)  
223 - {  
224 - $message = "ะ ะฐะทะผะตั€ ั„ะฐะนะปะฐ ะฝะต ัะพะพั‚ะฒะตั‚ัั‚ะฒัƒะตั‚ ะฝะพั€ะผะฐะผ";  
225 - }  
226 - else if (($_FILES['upload']["type"] != "image/jpeg") AND ($_FILES['upload']["type"] != "image/jpeg") AND ($_FILES['upload']["type"] != "image/png") AND ($_FILES['upload']['type'] != 'image/gif'))  
227 - {  
228 - $message = "ะ”ะพะฟัƒัะบะฐะตั‚ัั ะทะฐะณั€ัƒะทะบะฐ ั‚ะพะปัŒะบะพ ะบะฐั€ั‚ะธะฝะพะบ JPG ะธ PNG.";  
229 - }  
230 - else if (!is_uploaded_file($_FILES['upload']["tmp_name"]))  
231 - {  
232 - $message = "ะงั‚ะพ-ั‚ะพ ะฟะพัˆะปะพ ะฝะต ั‚ะฐะบ. ะŸะพะฟั‹ั‚ะฐะนั‚ะตััŒ ะทะฐะณั€ัƒะทะธั‚ัŒ ั„ะฐะนะป ะตั‰ั‘ ั€ะฐะท.";  
233 - }  
234 - else{  
235 - $filename = $_FILES['upload']['name'];  
236 - $name =$_FILES['upload']['name'].'.'.$this->getex($filename);  
237 -  
238 - $path = "../../storage/".$this->getUserPath()."/images/";  
239 - if(!is_dir($path)) {  
240 - mkdir($path, 0755, true);  
241 - }  
242 -  
243 -  
244 -  
245 - move_uploaded_file($_FILES['upload']['tmp_name'], $path.$name);  
246 -  
247 - $full_path = '/storage/'.$this->getUserPath().'/images/'.$name;  
248 -  
249 - $message = "ะคะฐะนะป ".$_FILES['upload']['name']." ะทะฐะณั€ัƒะถะตะฝ";  
250 -  
251 -  
252 - }  
253 - $callback = $_REQUEST['CKEditorFuncNum'];  
254 - echo '<script type="text/javascript">window.parent.CKEDITOR.tools.callFunction("'.$callback.'", "'.$full_path.'", "'.$message.'" );</script>';  
255 - }  
256 - }  
257 -  
258 -  
259 -}  
260 \ No newline at end of file 0 \ No newline at end of file
artbox-file/models/ImageSizerForm.php deleted
1 -<?php  
2 -namespace artweb\artbox\file\models;  
3 -  
4 -use yii\base\Model;  
5 -use yii\web\UploadedFile;  
6 -  
7 -/**  
8 - * UploadForm is the model behind the upload form.  
9 - */  
10 -class ImageSizerForm extends Model  
11 -{  
12 - /**  
13 - * @var UploadedFile file attribute  
14 - */  
15 - public $file;  
16 - public $width;  
17 - public $height;  
18 - public $field;  
19 - public $model;  
20 - public $form;  
21 - public $multi;  
22 - public $old_img;  
23 - public $img;  
24 - public $price_list;  
25 -  
26 - /**  
27 - * @return array the validation rules.  
28 - */  
29 - public function rules()  
30 - {  
31 - return [  
32 - [['width', 'height', 'multi'], 'integer'],  
33 - [['field', 'multi','old_img'], 'string', 'max' => 255],  
34 - [['model', 'form',], 'string'],  
35 - [['file','img','price_list'], 'file'],  
36 - ];  
37 - }  
38 -}  
39 \ No newline at end of file 0 \ No newline at end of file
artbox-file/views/_gallery_item.php deleted
1 -<?php  
2 -use yii\helpers\Html;  
3 -  
4 -?>  
5 -  
6 -<div class="col-xs-6 col-md-3 image-container">  
7 - <?= Html::img($item['image'])?>  
8 - <span data-url="<?=$item['image']?>" title="ัƒะดะฐะปะธั‚ัŒ ะธะทะพะฑั€ะฐะถะตะฝะธะต" class="glyphicon glyphicon-trash delete-gallery-item"></span>  
9 -</div>  
10 \ No newline at end of file 0 \ No newline at end of file
artbox-file/views/_one_item.php deleted
1 -<?php  
2 -  
3 -use yii\helpers\Html;  
4 -  
5 -?>  
6 -  
7 -<div class="col-xs-6 col-md-3 image-container">  
8 -  
9 - <div id="<?=$field?>_buttons_block">  
10 - <span title="ะ’ะตั€ะฝัƒั‚ัŒ ัั‚ะฐั€ัƒัŽ" id="<?=$field?>_remove_img" class="glyphicon glyphicon-repeat" ></span>  
11 - <span title="ะกะพั…ั€ะฐะฝะธั‚ัŒ" id="<?=$field?>_save_img" class="glyphicon glyphicon-ok" ></span>  
12 - </div>  
13 -  
14 - <?= Html::a( Html::img($item['image']),'#',['class'=>'thumbnail']) ?>  
15 -  
16 -</div>  
17 -  
artbox-file/widgets/ImageUploader.php deleted
1 -<?php  
2 -/**  
3 - * Created by PhpStorm.  
4 - * User: vitaliy  
5 - * Date: 05.10.15  
6 - * Time: 16:18  
7 - */  
8 -  
9 -namespace artweb\artbox\file\widgets;  
10 -use yii\base\Widget;  
11 -  
12 -  
13 -class ImageUploader extends Widget  
14 -{  
15 - public $height = 0;  
16 - public $width = 0;  
17 - public $field;  
18 - public $file;  
19 - public $model;  
20 - public $multi = false;  
21 - public $gallery;  
22 - public $size;  
23 - public $name = 'Add file...';  
24 - public $remover = 0;  
25 -  
26 - public function init(){  
27 -  
28 - parent::init();  
29 -  
30 - }  
31 -  
32 -  
33 - public function run()  
34 - {  
35 -  
36 - return $this->render('image_sizer',  
37 - [  
38 - 'model'=>$this->model,  
39 - 'size' => $this->size,  
40 - 'field' => $this->field,  
41 - 'height' => $this->height,  
42 - 'width' => $this->width,  
43 - 'multi' => $this->multi,  
44 - 'name' => $this->name,  
45 - 'remover' => $this->remover  
46 - ]);  
47 -  
48 - }  
49 -  
50 - public function getGallery(){  
51 - if($this->gallery){  
52 - $array = explode(",", $this->gallery);  
53 - if(count($array) > 1){  
54 - array_pop($array);  
55 - }  
56 - return $array;  
57 - } else {  
58 - return array();  
59 - }  
60 -  
61 - }  
62 -  
63 -}  
64 \ No newline at end of file 0 \ No newline at end of file
artbox-file/widgets/views/image_sizer.php deleted
1 -<?php  
2 -/**  
3 - * Created by PhpStorm.  
4 - * User: vitaliy  
5 - * Date: 05.10.15  
6 - * Time: 16:20  
7 - */  
8 -use artweb\artbox\file\models\ImageSizerForm;  
9 -use yii\helpers\Html;  
10 -  
11 -$id = $model->tableSchema->primaryKey[0];  
12 -  
13 -?>  
14 -  
15 - <?php if(!$multi):?>  
16 -<div class="row">  
17 -  
18 - <?= Html::activeHiddenInput( $model,$field,['id' => "{$field}_picture_link"]) ?>  
19 -  
20 -  
21 - <input type="hidden" id="<?=$field?>_old_img" name="ImageSizerForm[old_img]" value="<?=$model->$field?>"/>  
22 - <input type="hidden" id="<?=$field?>_new_img" name="ImageSizerForm[new_img]" value=""/>  
23 - <input type="hidden" id="<?=$field?>_row_id" name="ImageSizerForm[new_img]" value="<?=$model->$id?>"/>  
24 - <input type="hidden" id="<?=$field?>_row_field" name="ImageSizerForm[field]" value="<?=$field?>"/>  
25 - <div id="<?= $field?>_img_block">  
26 - <div class="col-xs-6 col-md-3 image-container">  
27 -  
28 - <?php if($remover && $model->$field): ?>  
29 - <span id="<?=$field?>_remove_img" class="remover_image glyphicon glyphicon-trash" ></span>  
30 - <?php endif; ?>  
31 -  
32 - <?php if($model->$field):?>  
33 - <?= Html::a(Html::img($model->$field),'#',['class'=>'thumbnail']) ?>  
34 - <?php endif; ?>  
35 - </div>  
36 - </div>  
37 -  
38 -</div>  
39 -<div class="row">  
40 - <span class="btn btn-success fileinput-button uploader-button">  
41 - <!-- <i class="glyphicon glyphicon-plus"></i>-->  
42 - <span><?=$name?></span>  
43 -  
44 - <?= Html::activeFileInput( new ImageSizerForm(),'file',['id'=>$field, 'data-url'=>Yii::$app->getUrlManager()->createUrl('file/uploader/download-photo')]);?>  
45 - </span>  
46 -</div>  
47 -  
48 -  
49 -  
50 -  
51 -  
52 -  
53 -  
54 -  
55 -  
56 - <script>  
57 - $(function()  
58 - {  
59 -  
60 - $("#<?= $field?>").fileupload(  
61 - {  
62 - dataType : 'json', formData : {size : '<?= json_encode($size)?>',field:'<?= $field ?>'},  
63 - done : function(e, data)  
64 - {  
65 - if($("#<?=$field?>_buttons_block").length)  
66 - {  
67 - $("#<?=$field?>_buttons_block").remove()  
68 - }  
69 -  
70 - $("#<?= $field?>").parent().prev().find('.admin-ava-wr').remove()  
71 -  
72 - var img = data.result.view;  
73 -  
74 - var block = $("#<?= $field?>_img_block");  
75 -  
76 - block.find('.image-container').remove();  
77 -  
78 - block.append(img);  
79 -  
80 - $("#<?=$field?>_picture_link").val(data.result.link);  
81 -  
82 - $("#<?=$field?>_new_img").val(data.result.link);  
83 -  
84 - }  
85 - }  
86 - );  
87 -  
88 - $('body').on(  
89 - 'click', '#<?=$field?>_save_img', function()  
90 - {  
91 -  
92 - $("#<?=$field?>_buttons_block").remove();  
93 -  
94 -  
95 - var old_url = $('#<?=$field?>_old_img').val();  
96 - var new_url = $('#<?=$field?>_new_img').val();  
97 - var model = '<?=str_replace('\\', '-', $model::className());?>';  
98 - $.post(  
99 - "/file/uploader/delete-image", {  
100 - new_url : new_url, old_img : old_url, model : model, field : "<?= $field?>",  
101 - id : "<?=$model->$id?>", action : 'save'  
102 - }, function()  
103 - {  
104 - }  
105 - );  
106 - $("#<?=$field?>_picture_link").val(new_url);  
107 - }  
108 - );  
109 -  
110 - $('body').on(  
111 - 'click', '#<?=$field?>_remove_img', function()  
112 - {  
113 - $("#<?=$field?>_buttons_block").remove();  
114 -  
115 - var old_url = $('#<?=$field?>_old_img').val();  
116 - var new_url = $('#<?=$field?>_new_img').val();  
117 - $.post(  
118 - "/file/uploader/delete-image", {old_img : new_url}, function()  
119 - {  
120 - }  
121 - );  
122 - if(<?=$remover?>){  
123 -  
124 - $("#<?=$field?>_picture_link").val('');  
125 - $('#<?=$field?>_img_block').find('img').remove();  
126 -  
127 - } else {  
128 -  
129 - $("#<?=$field?>_picture_link").val(old_url);  
130 -  
131 - if(old_url.length<=1){  
132 - $('#<?=$field?>_img_block').find('img').remove()  
133 - }  
134 - else {  
135 - console.log(old_url);  
136 - $('#<?=$field?>_img_block').find('img').attr('src',old_url);  
137 - }  
138 -  
139 - }  
140 -  
141 - }  
142 - );  
143 - });  
144 -</script>  
145 -  
146 -<?php else:?>  
147 -  
148 - <span class="btn btn-success fileinput-button uploader-button">  
149 - <i class="glyphicon glyphicon-plus"></i>  
150 - <span><?=$name?></span>  
151 -  
152 - <?= Html::activeFileInput( new ImageSizerForm(),'file',['id'=>$field, 'data-url'=>Yii::$app->getUrlManager()->createUrl('file/uploader/download-photo'), 'multiple'=> 'multiple' ]);?>  
153 - </span>  
154 -  
155 - <?= Html::activeHiddenInput( $model,$field,['id' => "{$field}_picture_link"]) ?>  
156 -  
157 -  
158 - <input type="hidden" name="ImageSizerForm[multi]" value="true"/>  
159 -  
160 - <div id="<?= $field?>_img_block">  
161 - <?php  
162 -  
163 - foreach($this->context->getGallery() as $image){  
164 - echo $this->render('@common/modules/file/views/_gallery_item', [ 'item' => ['image'=>$image]]);  
165 - }  
166 - ?>  
167 - </div>  
168 - <script>  
169 - $(function(){  
170 -  
171 - $("#<?= $field?>").fileupload({  
172 - dataType: 'json',  
173 - formData: {size:'<?= json_encode($size)?>', multi: 1,field : "<?= $field?>"},  
174 - done: function (e, data) {  
175 - var img = data.result.view;  
176 - var block = $("#<?= $field?>_img_block");  
177 - block.append(img);  
178 - var gallery = $("#<?= $field?>_picture_link");  
179 - gallery.val(gallery.val()+data.result.link+',');  
180 - }  
181 - });  
182 - $('body').on('click','.delete-gallery-item', function(){  
183 - var url = $(this).data('url');  
184 - $(this).parent('.image-container').remove();  
185 - var gallery = $("#<?= $field?>_picture_link");  
186 -  
187 -  
188 -  
189 - var urls = gallery.val();  
190 -  
191 -  
192 - gallery.val(urls.replace(url+',', ""));  
193 -  
194 -  
195 - $.post( "/file/uploader/delete-image",{old_img: url}, function( data ) {  
196 - $( ".result" ).html( data );  
197 - });  
198 - })  
199 -  
200 - })  
201 - </script>  
202 -  
203 -<?php endif;?>  
artbox-language/Module.php deleted
1 -<?php  
2 -  
3 - namespace common\modules;  
4 -  
5 - class Module extends \yii\base\Module  
6 - {  
7 -  
8 - public function init()  
9 - {  
10 - parent::init();  
11 - }  
12 - }  
13 \ No newline at end of file 0 \ No newline at end of file
artbox-language/behaviors/LanguageBehavior.php deleted
1 -<?php  
2 - namespace artweb\artbox\language\behaviors;  
3 -  
4 - use artweb\artbox\language\models\Language;  
5 - use yii\base\Behavior;  
6 - use yii\base\InvalidConfigException;  
7 - use yii\db\ActiveQuery;  
8 - use yii\db\ActiveRecord;  
9 - use yii\db\Transaction;  
10 - use yii\web\Request;  
11 -  
12 - /**  
13 - * Class LanguageBehavior  
14 - * @property ActiveRecord $owner  
15 - * @property string $ownerKey  
16 - * @property string $langKey  
17 - * @property ActiveRecord[] $langs  
18 - * @property ActiveRecord $lang  
19 - */  
20 - class LanguageBehavior extends Behavior  
21 - {  
22 -  
23 - /**  
24 - * @var ActiveRecord $objectLang Empty language model for $owner  
25 - */  
26 - public $objectLang;  
27 -  
28 - /**  
29 - * @var ActiveRecord[] $modelLangs  
30 - */  
31 - public $modelLangs = [];  
32 -  
33 - private $ownerKey;  
34 -  
35 - private $langKey;  
36 -  
37 - /**  
38 - * @var Transaction $transaction  
39 - */  
40 - private $transaction;  
41 -  
42 - /**  
43 - * @var bool $transactionStatus  
44 - */  
45 - private $transactionStatus = false;  
46 -  
47 - public function events()  
48 - {  
49 - return [  
50 - ActiveRecord::EVENT_BEFORE_INSERT => 'beforeSave',  
51 - ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeSave',  
52 - ActiveRecord::EVENT_AFTER_INSERT => 'afterSave',  
53 - ActiveRecord::EVENT_AFTER_UPDATE => 'afterSave',  
54 - ];  
55 - }  
56 -  
57 - /**  
58 - * Get $owner primary key to link language model  
59 - * @return string  
60 - */  
61 - public function getOwnerKey():string  
62 - {  
63 - if(!empty( $this->ownerKey )) {  
64 - return $this->ownerKey;  
65 - } else {  
66 - return $this->owner->primaryKey()[ 0 ];  
67 - }  
68 - }  
69 -  
70 - /**  
71 - * Set which attribute to use as $owner primary key to link language model  
72 - *  
73 - * @param string $value  
74 - */  
75 - public function setOwnerKey(string $value)  
76 - {  
77 - $this->ownerKey = $value;  
78 - }  
79 -  
80 - /**  
81 - * Get language model attribute that is used as foreign key to $owner  
82 - * @return string  
83 - */  
84 - public function getLangKey():string  
85 - {  
86 - if(!empty( $this->langKey )) {  
87 - return $this->langKey;  
88 - } else {  
89 - $owner = $this->owner;  
90 - return $owner::getTableSchema()->name . '_id';  
91 - }  
92 - }  
93 -  
94 - /**  
95 - * Set which attribute to use as language model foreign key to $owner  
96 - *  
97 - * @param $value  
98 - */  
99 - public function setLangKey(string $value)  
100 - {  
101 - $this->langKey = $value;  
102 - }  
103 -  
104 - /**  
105 - * Additional checks to attach this behavior  
106 - *  
107 - * @param ActiveRecord $owner  
108 - *  
109 - * @throws InvalidConfigException  
110 - */  
111 - public function attach($owner)  
112 - {  
113 - if(empty( $this->objectLang )) {  
114 - $this->objectLang = $owner::className() . 'Lang';  
115 - } elseif(!is_string($this->objectLang)) {  
116 - throw new InvalidConfigException('Object lang must be fully classified namespaced classname');  
117 - }  
118 - try {  
119 - $this->objectLang = \Yii::createObject($this->objectLang);  
120 - } catch(\ReflectionException $exception) {  
121 - throw new InvalidConfigException('Object lang must be fully classified namespaced classname');  
122 - }  
123 - if(( !$owner instanceof ActiveRecord ) || ( !$this->objectLang instanceof ActiveRecord )) {  
124 - throw new InvalidConfigException('Object lang must be fully classified namespaced classname');  
125 - }  
126 - parent::attach($owner);  
127 - }  
128 -  
129 - /**  
130 - * Get query to get all language models for $owner indexed by language_id  
131 - * @return ActiveQuery  
132 - */  
133 - public function getLangs()  
134 - {  
135 - $objectLang = $this->objectLang;  
136 - $owner = $this->owner;  
137 - return $owner->hasMany($objectLang::className(), [ $this->getLangKey() => $this->getOwnerKey() ])  
138 - ->indexBy('language_id');  
139 - }  
140 -  
141 - /**  
142 - * Get query to get language model for $owner for language_id, default to  
143 - * Language::getCurrent()  
144 - *  
145 - * @param int $language_id  
146 - *  
147 - * @return ActiveQuery  
148 - */  
149 - public function getLang(int $language_id = NULL)  
150 - {  
151 - if(empty( $language_id )) {  
152 - $language_id = Language::getCurrent()->id;  
153 - }  
154 - $objectLang = $this->objectLang;  
155 - $table_name = $objectLang::getTableSchema()->name;  
156 - $owner = $this->owner;  
157 - return $owner->hasOne($objectLang::className(), [ $this->getLangKey() => $this->getOwnerKey() ])  
158 - ->where([ $table_name . '.language_id' => $language_id ]);  
159 - }  
160 -  
161 - /**  
162 - * Generate language models for $owner for active languages. If $owner not new and language  
163 - * models already inserted, models will be filled with them.  
164 - * @return void  
165 - */  
166 - public function generateLangs()  
167 - {  
168 - $owner = $this->owner;  
169 - $languages = Language::find()  
170 - ->where([ 'status' => true ])  
171 - ->orderBy([ 'id' => SORT_ASC ])  
172 - ->asArray()  
173 - ->column();  
174 - $objectLang = $this->objectLang;  
175 - $owner_key = $this->getOwnerKey();  
176 - $langs = [];  
177 - if(!$owner->isNewRecord) {  
178 - $langs = $this->getLangs()  
179 - ->andFilterWhere([ 'language_id' => $languages ])  
180 - ->orderBy([ 'language_id' => SORT_ASC ])  
181 - ->all();  
182 - }  
183 - foreach($languages as $language) {  
184 - if(!array_key_exists($language, $langs)) {  
185 - $langs[ $language ] = \Yii::createObject([  
186 - 'class' => $objectLang::className(),  
187 - 'language_id' => $language,  
188 - $this->getLangKey() => ( $owner->isNewRecord ? NULL : $owner->$owner_key ),  
189 - ]);  
190 - }  
191 - }  
192 - $this->modelLangs = $langs;  
193 - }  
194 -  
195 - /**  
196 - * Load language models with post data.  
197 - *  
198 - * @param Request $request  
199 - */  
200 - public function loadLangs(Request $request)  
201 - {  
202 - foreach($request->post($this->objectLang->formName(), []) as $lang => $value) {  
203 - if(!empty( $this->modelLangs[ $lang ] )) {  
204 - $this->modelLangs[ $lang ]->attributes = $value;  
205 - $this->modelLangs[ $lang ]->language_id = $lang;  
206 - }  
207 - }  
208 - }  
209 -  
210 - /**  
211 - * Link language models with $owner by setting language model language key to owner key of  
212 - * owner  
213 - * @return bool If $owner is new record then return false else true  
214 - */  
215 - public function linkLangs()  
216 - {  
217 - $owner = $this->owner;  
218 - // if($owner->isNewRecord) {  
219 - // return false;  
220 - // }  
221 - $lang_key = $this->getLangKey();  
222 - $owner_key = $this->getOwnerKey();  
223 - $modelLangs = $this->modelLangs;  
224 - foreach($modelLangs as $model_lang) {  
225 - $model_lang->$lang_key = $owner->$owner_key;  
226 - }  
227 - return true;  
228 - }  
229 -  
230 - /**  
231 - * Try to save all language models to the db. Validation function is run for all models.  
232 - * @return bool Whether all models are valid  
233 - */  
234 - public function saveLangs()  
235 - {  
236 - $success = true;  
237 - $modelLangs = $this->modelLangs;  
238 - foreach($modelLangs as $model_lang) {  
239 - if($model_lang->save() === false) {  
240 - $success = false;  
241 - }  
242 - }  
243 - return $success;  
244 - }  
245 -  
246 - public function beforeSave($event)  
247 - {  
248 - /**  
249 - * @var ActiveRecord $owner  
250 - */  
251 - $owner = $this->owner;  
252 - $db = $owner::getDb();  
253 - $this->transaction = $db->beginTransaction();  
254 - if($owner->hasAttribute('remote_id') && empty( $owner->remote_id )) {  
255 - $owner->remote_id = strval(microtime(true) * 10000);  
256 - }  
257 - }  
258 -  
259 - public function afterSave($event)  
260 - {  
261 - if(!empty( $this->modelLangs )) {  
262 - if($this->linkLangs() && $this->saveLangs()) {  
263 - $this->transaction->commit();  
264 - $this->transactionStatus = true;  
265 - } else {  
266 - $this->transaction->rollBack();  
267 - $this->transactionStatus = false;  
268 - }  
269 - } else {  
270 - $this->transaction->commit();  
271 - $this->transactionStatus = true;  
272 - }  
273 - }  
274 -  
275 - /**  
276 - * @return bool  
277 - */  
278 - public function getTransactionStatus():bool  
279 - {  
280 - return $this->transactionStatus;  
281 - }  
282 - }  
283 \ No newline at end of file 0 \ No newline at end of file
artbox-language/components/LanguageRequest.php deleted
1 -<?php  
2 -  
3 - namespace artweb\artbox\language\components;  
4 -  
5 - use artweb\artbox\language\models\Language;  
6 - use yii\base\InvalidConfigException;  
7 - use yii\web\Request;  
8 -  
9 - class LanguageRequest extends Request  
10 - {  
11 -  
12 - private $languageUrl;  
13 -  
14 - public function getLanguageUrl()  
15 - {  
16 - if($this->languageUrl === NULL) {  
17 - $this->languageUrl = $this->getUrl();  
18 -  
19 - $url_list = explode('/', $this->languageUrl);  
20 -  
21 - $language_url = isset( $url_list[ 1 ] ) ? $url_list[ 1 ] : NULL;  
22 - Language::setCurrent($language_url);  
23 -  
24 - if($language_url !== NULL && $language_url === Language::getCurrent()->url && strpos($this->languageUrl, Language::getCurrent()->url) === 1) {  
25 - $this->languageUrl = substr($this->languageUrl, strlen(Language::getCurrent()->url) + 1);  
26 - }  
27 - }  
28 -  
29 - return $this->languageUrl;  
30 - }  
31 -  
32 - protected function resolvePathInfo()  
33 - {  
34 - $pathInfo = $this->getLanguageUrl();  
35 -  
36 - if(( $pos = strpos($pathInfo, '?') ) !== false) {  
37 - $pathInfo = substr($pathInfo, 0, $pos);  
38 - }  
39 -  
40 - $pathInfo = urldecode($pathInfo);  
41 -  
42 - if(!preg_match('%^(?:  
43 - [\x09\x0A\x0D\x20-\x7E]  
44 - | [\xC2-\xDF][\x80-\xBF]  
45 - | \xE0[\xA0-\xBF][\x80-\xBF]  
46 - | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  
47 - | \xED[\x80-\x9F][\x80-\xBF]  
48 - | \xF0[\x90-\xBF][\x80-\xBF]{2}  
49 - | [\xF1-\xF3][\x80-\xBF]{3}  
50 - | \xF4[\x80-\x8F][\x80-\xBF]{2}  
51 - )*$%xs', $pathInfo)  
52 - ) {  
53 - $pathInfo = utf8_encode($pathInfo);  
54 - }  
55 -  
56 - $scriptUrl = $this->getScriptUrl();  
57 - $baseUrl = $this->getBaseUrl();  
58 -  
59 - if(strpos($pathInfo, $scriptUrl) === 0) {  
60 - $pathInfo = substr($pathInfo, strlen($scriptUrl));  
61 - } elseif($baseUrl === '' || strpos($pathInfo, $baseUrl) === 0) {  
62 - $pathInfo = substr($pathInfo, strlen($baseUrl));  
63 - } elseif(isset( $_SERVER[ 'PHP_SELF' ] ) && strpos($_SERVER[ 'PHP_SELF' ], $scriptUrl) === 0) {  
64 - $pathInfo = substr($_SERVER[ 'PHP_SELF' ], strlen($scriptUrl));  
65 - } else {  
66 - throw new InvalidConfigException('Unable to determine the path info of the current request.');  
67 - }  
68 -  
69 - if($pathInfo === '/') {  
70 - $pathInfo = substr($pathInfo, 1);  
71 - }  
72 -  
73 - return (string) $pathInfo;  
74 - }  
75 - }  
76 \ No newline at end of file 0 \ No newline at end of file
artbox-language/components/LanguageUrlManager.php deleted
1 -<?php  
2 - namespace artweb\artbox\language\components;  
3 -  
4 - use artweb\artbox\language\models\Language;  
5 - use yii\web\UrlManager;  
6 -  
7 - class LanguageUrlManager extends UrlManager  
8 - {  
9 -  
10 - /**  
11 - * @inheritdoc  
12 - */  
13 - public function createUrl($params)  
14 - {  
15 - if(isset( $params[ 'language_id' ] )) {  
16 -  
17 - $language = Language::findOne($params[ 'language_id' ]);  
18 - if($language === NULL) {  
19 - $language = Language::getDefaultLanguage();  
20 - }  
21 - unset( $params[ 'language_id' ] );  
22 - } else {  
23 -  
24 - $language = Language::getCurrent();  
25 - }  
26 -  
27 - $url = parent::createUrl($params);  
28 -  
29 - if($url == '/') {  
30 - return '/' . $language->url;  
31 - } else {  
32 - return '/' . $language->url . $url;  
33 - }  
34 - }  
35 - }  
36 \ No newline at end of file 0 \ No newline at end of file
artbox-language/composer.json deleted
1 -{  
2 - "name": "artweb/artbox-language",  
3 - "description": "Yii2 light-weight CMS",  
4 - "license": "BSD-3-Clause",  
5 - "require": {  
6 - "php": ">=7.0",  
7 - "yiisoft/yii2": "*",  
8 - "developeruz/yii2-db-rbac": "*"  
9 - },  
10 - "autoload": {  
11 - "psr-4": {  
12 - "artweb\\artbox\\language\\": ""  
13 - }  
14 - }  
15 -}  
16 \ No newline at end of file 0 \ No newline at end of file
artbox-language/migrations/m160829_104745_create_table_language.php deleted
1 -<?php  
2 -  
3 - use yii\db\Migration;  
4 -  
5 - class m160829_104745_create_table_language extends Migration  
6 - {  
7 -  
8 - public function up()  
9 - {  
10 - $this->createTable(  
11 - '{{%language}}',  
12 - [  
13 - 'id' => $this->primaryKey(),  
14 - 'url' => $this->string()  
15 - ->notNull(),  
16 - 'local' => $this->string()  
17 - ->notNull(),  
18 - 'name' => $this->string()  
19 - ->notNull(),  
20 - 'default' => $this->boolean()  
21 - ->notNull()  
22 - ->defaultValue(false),  
23 - 'created_at' => $this->integer()  
24 - ->notNull(),  
25 - 'updated_at' => $this->integer()  
26 - ->notNull(),  
27 - ]  
28 - );  
29 - }  
30 -  
31 - public function down()  
32 - {  
33 - $this->dropTable('{{%language}}');  
34 - }  
35 - }  
artbox-language/migrations/m160829_105345_add_default_languages.php deleted
1 -<?php  
2 -  
3 - use yii\db\Migration;  
4 -  
5 - class m160829_105345_add_default_languages extends Migration  
6 - {  
7 -  
8 - public function up()  
9 - {  
10 - $this->batchInsert(  
11 - '{{%language}}',  
12 - [  
13 - 'id',  
14 - 'url',  
15 - 'local',  
16 - 'name',  
17 - 'default',  
18 - 'created_at',  
19 - 'updated_at',  
20 - ],  
21 - [  
22 - [  
23 - 1,  
24 - 'en',  
25 - 'en-EN',  
26 - 'English',  
27 - 0,  
28 - time(),  
29 - time(),  
30 - ],  
31 - [  
32 - 2,  
33 - 'ru',  
34 - 'ru-RU',  
35 - 'ะ ัƒััะบะธะน',  
36 - 1,  
37 - time(),  
38 - time(),  
39 - ],  
40 - ]  
41 - );  
42 - }  
43 -  
44 - public function down()  
45 - {  
46 - $this->delete(  
47 - '{{%language}}',  
48 - [  
49 - 'id' => [  
50 - 1,  
51 - 2,  
52 - ],  
53 - ]  
54 - );  
55 - }  
56 - }  
artbox-language/migrations/m160901_140639_add_ukrainian_language.php deleted
1 -<?php  
2 -  
3 - use yii\db\Migration;  
4 -  
5 - class m160901_140639_add_ukrainian_language extends Migration  
6 - {  
7 -  
8 - public function up()  
9 - {  
10 - $this->batchInsert(  
11 - '{{%language}}',  
12 - [  
13 - 'id',  
14 - 'url',  
15 - 'local',  
16 - 'name',  
17 - 'default',  
18 - 'created_at',  
19 - 'updated_at',  
20 - ],  
21 - [  
22 - [  
23 - 3,  
24 - 'ua',  
25 - 'ua-UA',  
26 - 'ะฃะบั€ะฐั—ะฝััŒะบะฐ',  
27 - 0,  
28 - time(),  
29 - time(),  
30 - ],  
31 - ]  
32 - );  
33 - }  
34 -  
35 - public function down()  
36 - {  
37 - $this->delete('{{%language}}', [ 'id' => [ 3 ] ]);  
38 - }  
39 - }  
artbox-language/migrations/m160927_124151_add_status_column.php deleted
1 -<?php  
2 -  
3 - use yii\db\Migration;  
4 -  
5 - class m160927_124151_add_status_column extends Migration  
6 - {  
7 -  
8 - public function up()  
9 - {  
10 - $this->addColumn('language', 'status', $this->boolean()  
11 - ->notNull()  
12 - ->defaultValue(false));  
13 - }  
14 -  
15 - public function down()  
16 - {  
17 - $this->dropColumn('language', 'status');  
18 - }  
19 - }  
artbox-language/models/Language.php deleted
1 -<?php  
2 -  
3 - namespace artweb\artbox\language\models;  
4 -  
5 - use Yii;  
6 - use yii\db\ActiveRecord;  
7 -  
8 - /**  
9 - * This is the model class for table "language".  
10 - *  
11 - * @property integer $id  
12 - * @property string $url  
13 - * @property string $local  
14 - * @property string $name  
15 - * @property boolean $default  
16 - * @property integer $created_at  
17 - * @property integer $updated_at  
18 - */  
19 - class Language extends ActiveRecord  
20 - {  
21 -  
22 - /**  
23 - * @var null|self  
24 - */  
25 - public static $current = null;  
26 -  
27 - /**  
28 - * @inheritdoc  
29 - */  
30 - public static function tableName()  
31 - {  
32 - return 'language';  
33 - }  
34 -  
35 - /**  
36 - * @inheritdoc  
37 - */  
38 - public function behaviors()  
39 - {  
40 - return [  
41 - 'timestamp' => [  
42 - 'class' => 'yii\behaviors\TimestampBehavior',  
43 - 'attributes' => [  
44 - ActiveRecord::EVENT_BEFORE_INSERT => [  
45 - 'created_at',  
46 - 'updated_at',  
47 - ],  
48 - ActiveRecord::EVENT_BEFORE_UPDATE => [  
49 - 'updated_at',  
50 - ],  
51 - ],  
52 - ],  
53 - ];  
54 - }  
55 -  
56 - /**  
57 - * @inheritdoc  
58 - */  
59 - public function rules()  
60 - {  
61 - return [  
62 - [  
63 - [  
64 - 'url',  
65 - 'local',  
66 - 'name',  
67 - 'created_at',  
68 - 'updated_at',  
69 - ],  
70 - 'required',  
71 - ],  
72 - [  
73 - [ 'default' ],  
74 - 'boolean',  
75 - ],  
76 - [  
77 - [  
78 - 'created_at',  
79 - 'updated_at',  
80 - ],  
81 - 'integer',  
82 - ],  
83 - [  
84 - [  
85 - 'url',  
86 - 'local',  
87 - 'name',  
88 - ],  
89 - 'string',  
90 - 'max' => 255,  
91 - ],  
92 - ];  
93 - }  
94 -  
95 - /**  
96 - * @inheritdoc  
97 - */  
98 - public function attributeLabels()  
99 - {  
100 - return [  
101 - 'id' => Yii::t('app', 'Language ID'),  
102 - 'url' => Yii::t('app', 'Url'),  
103 - 'local' => Yii::t('app', 'Local'),  
104 - 'name' => Yii::t('app', 'Name'),  
105 - 'default' => Yii::t('app', 'Default'),  
106 - 'created_at' => Yii::t('app', 'Date Create'),  
107 - 'updated_at' => Yii::t('app', 'Date Update'),  
108 - ];  
109 - }  
110 -  
111 - /**  
112 - * Get current language  
113 - *  
114 - * @return null|Language  
115 - */  
116 - public static function getCurrent()  
117 - {  
118 - if (self::$current === null) {  
119 - self::$current = self::getDefaultLanguage();  
120 - }  
121 - return self::$current;  
122 - }  
123 -  
124 - /**  
125 - * Set current language by Url param  
126 - *  
127 - * @param null|string $url Language url param  
128 - */  
129 - public static function setCurrent($url = null)  
130 - {  
131 - $language = self::getLanguageByUrl($url);  
132 - self::$current = ( $language === null ) ? self::getDefaultLanguage() : $language;  
133 - Yii::$app->language = self::$current->local;  
134 - }  
135 -  
136 - /**  
137 - * Get default language  
138 - *  
139 - * @return null|Language  
140 - */  
141 - public static function getDefaultLanguage()  
142 - {  
143 - /**  
144 - * @var null|Language $language  
145 - */  
146 - $language = self::find()  
147 - ->where([ 'default' => true ])  
148 - ->one();  
149 - return $language;  
150 - }  
151 -  
152 - /**  
153 - * Get language by Url param  
154 - *  
155 - * @param null|string $url Language url param  
156 - *  
157 - * @return null|Language  
158 - */  
159 - public static function getLanguageByUrl($url = null)  
160 - {  
161 - if ($url === null) {  
162 - return null;  
163 - } else {  
164 - /**  
165 - * @var null|Language $language  
166 - */  
167 - $language = self::find()  
168 - ->where([ 'url' => $url ])  
169 - ->one();  
170 - if ($language === null) {  
171 - return null;  
172 - } else {  
173 - return $language;  
174 - }  
175 - }  
176 - }  
177 - }  
artbox-language/readme.txt deleted
1 -ะšะฐะบ ะฒะบะปัŽั‡ะธั‚ัŒ ะผัƒะปัŒั‚ะธัะทั‹ั‡ะฝะพัั‚ัŒ ะฝะฐ ัะฐะนั‚ะต:  
2 -1. ะ—ะฐะฟัƒัะบะฐะตะผ ะผะธะณั€ะฐั†ะธัŽ: php yii migrate --migrationPath=common/modules/language/migrations  
3 -2. ะ”ะพะฑะฐะฒะปัะตะผ ะฒ ั„ะฐะนะป ะบะพะฝั„ะธะณัƒั€ะฐั†ะธะธ:  
4 -'urlManager' => [  
5 - 'enablePrettyUrl' => true,  
6 - 'showScriptName' => false,  
7 - 'class'=>'artweb\artbox\language\components\LanguageUrlManager',  
8 - 'rules'=>[  
9 - '/' => 'site/index',  
10 - '<controller:\w+>/<action:\w+>/*'=>'<controller>/<action>',  
11 - ]  
12 -],  
13 -3. ะ”ะพะฑะฐะฒะปัะตะผ ะฒ ั„ะฐะนะป ะบะพะฝั„ะธะณัƒั€ะฐั†ะธะธ:  
14 -'request' => [  
15 - 'class' => 'artweb\artbox\language\components\LanguageRequest'  
16 -],  
17 -4. ะ”ะพะฑะฐะฒะปัะตะผ ะฒ ั„ะฐะนะป ะบะพะฝั„ะธะณัƒั€ะฐั†ะธะธ:  
18 -'language'=>'ru-RU',  
19 -'i18n' => [  
20 - 'translations' => [  
21 - '*' => [  
22 - 'class' => 'yii\i18n\PhpMessageSource',  
23 - 'basePath' => '@frontend/messages',  
24 - 'sourceLanguage' => 'en',  
25 - 'fileMap' => [  
26 - ],  
27 - ],  
28 - ],  
29 -],  
30 -5. ะŸะตั€ะตะฒะพะดั‹ ะฟะธัะฐั‚ัŒ ะฒ ั„ะฐะนะป frontend\messages\{language}\app.php, ะณะดะต {language} - ะฝัƒะถะฝั‹ะน ัะทั‹ะบ, ะฝะฐะฟั€ะธะผะตั€ ru.  
31 -6. ะ”ะปั ะฒั‹ะฒะพะดะฐ ะฝะฐ ัั‚ั€ะฐะฝะธั†ะต ัะพะพะฑั‰ะตะฝะธั ั ะฟะตั€ะตะฒะพะดะพะผ ะธัะฟะพะปัŒะทัƒะตะผ ั„ัƒะฝะบั†ะธัŽ: Yii::t('app', {message}, $params = [], $language = null),  
32 - ะณะดะต {message} - ะฝัƒะถะฝะพะต ัะพะพะฑั‰ะตะฝะธะต, $params - ะผะฐััะธะฒ ะฟะฐั€ะฐะผะตั‚ั€ะพะฒ, $language - ะฝัƒะถะฝั‹ะน ัะทั‹ะบ (ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ ะธัะฟะพะปัŒะทัƒะตั‚ัั ั‚ะตะบัƒั‰ะธะน ัะทั‹ะบ).  
33 -7. ะ’ ะฝะฐะปะธั‡ะธะต ั‚ะฐะบะถะต ะฒะธะดะถะตั‚ ะฟะตั€ะตะบะปัŽั‡ะตะฝะธั ัะทั‹ะบะฐ: LanguagePicker::widget()  
34 -  
35 -  
36 -ะšะฐะบ ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ ะผัƒะปัŒั‚ะธัะทั‹ั‡ะฝะพัั‚ัŒ ะดะปั Active Record:  
37 -1. ะกะพะทะดะฐะตะผ ะดะปั ั‚ะฐะฑะปะธั†ั‹ {table} ั‚ะฐะฑะปะธั†ัƒ ั ัะทั‹ะบะฐะผะธ {table_lang}.  
38 -2. ะกะพะทะดะฐะตะผ ะดะปั ะบะปะฐััะฐ {Table} ะบะปะฐัั ั ัะทั‹ะบะฐะผะธ {TableLang}.  
39 -3. ะŸะพะดะบะปัŽั‡ะฐะตะธ ะดะปั ะบะปะฐััะฐ {Table} ะฟะพะฒะตะดะตะฝะธะต LanguageBehavior:  
40 -public function behaviors() {  
41 - return [  
42 - 'language' => [  
43 - 'class' => LanguageBehavior::className(),  
44 - 'objectLang' => {TableLang}::className() // optional, default to {TableLang}::className()  
45 - 'ownerKey' => {Table}->id //optional, default to {Table}->primaryKey()[0]  
46 - 'langKey' => {TableLang}->table_id //optional, default to {Table}->tableName().'_id'  
47 - ],  
48 - ];  
49 -}  
50 -3.1. PHPDoc ะดะปั {Table}:  
51 - * * From language behavior *  
52 - * @property {TableLang} $lang  
53 - * @property {TableLang}[] $langs  
54 - * @property {TableLang} $objectLang  
55 - * @property string $ownerKey  
56 - * @property string $langKey  
57 - * @property {TableLang}[] $modelLangs  
58 - * @property bool $transactionStatus  
59 - * @method string getOwnerKey()  
60 - * @method void setOwnerKey(string $value)  
61 - * @method string getLangKey()  
62 - * @method void setLangKey(string $value)  
63 - * @method ActiveQuery getLangs()  
64 - * @method ActiveQuery getLang( integer $language_id )  
65 - * @method {TableLang}[] generateLangs()  
66 - * @method void loadLangs(Request $request)  
67 - * @method bool linkLangs()  
68 - * @method bool saveLangs()  
69 - * @method bool getTransactionStatus()  
70 - * * End language behavior *  
71 -3.2. ะฃะฑั€ะฐั‚ัŒ language behavior ั ะฝะฐัะปะตะดัƒะตะผั‹ั… ั‚ะฐะฑะปะธั† ะพั‚ {Table} ({TableSearch}...)  
72 -4. ะ”ะพัั‚ัƒะฟะฝั‹ะต ะฟะพะปะตะทะฝั‹ะต ะผะตั‚ะพะดั‹:  
73 - {Table}->getLangs() - ะฟะพะปัƒั‡ะธั‚ัŒ ะฒัะต ั‚ะตะบัƒั‰ะธะต {TableLang} ะดะปั {Table} ะฟั€ะพะธะฝะดะตะบัะธั€ะพะฒะฐะฝะฝั‹ะต ะฟะพ language_id  
74 - {Table}->getLang($language_id = NULL) - ะฟะพะปัƒั‡ะธั‚ัŒ {TableLang} ะดะปั ะพะฟั€ะตะดะตะปะตะฝะฝะพะณะพ ัะทั‹ะบะฐ (default: ั‚ะตะบัƒั‰ะธะน ัะทั‹ะบ) ะดะปั {Table}  
75 - {Table}->generateLangs() - ะฟะพะปัƒั‡ะธั‚ัŒ ะผะฐััะธะฒ {TableLang} ะฟะพะด ะบะฐะถะดั‹ะน ัะทั‹ะบ, ะฒะบะปัŽั‡ะฐั ััƒั‰ะตัั‚ะฒัƒัŽั‰ะธะต ะทะฐะฟะธัะธ, ะดะปั {Table}  
76 - {Table}->loadLangs($request) - ะทะฐะฟะพะปะฝะธั‚ัŒ ะผะฐััะธะฒ {TableLang} ะดะฐะฝะฝั‹ะผะธ ั POST  
77 - {Table}->linkLangs() - ัะฒัะทะฐั‚ัŒ ะบะฐะถะดั‹ะน ัะปะตะผะตะฝั‚ ะผะฐััะธะฒะฐ {TableLang} ั ั‚ะตะบัƒั‰ะตะน {Table}  
78 - {Table}->saveLangs() - ะฟั€ะพะฒะฐะปะธะดะธั€ะพะฒะฐั‚ัŒ ะธ ัะพั…ั€ะฐะฝะธั‚ัŒ ะบะฐะถะดั‹ะน ัะปะตะผะตะฝั‚ ะผะฐััะธะฒะฐ {TableLang}  
79 -5. ะ”ะพะฑะฐะฒะธั‚ัŒ ะฟะพะปั ะฒ ั„ะพั€ะผัƒ (ะบ ะฟั€ะธะผะตั€ัƒ ั‡ะตั€ะตะท Bootstrap Tabs).  
80 - ะ’ ะฝะฐะปะธั‡ะธะธ:  
81 - LanguageForm::widget([  
82 - 'modelLangs' => {TableLang}[],  
83 - 'formView' => string,  
84 - 'form' => ActiveForm,  
85 - ]);  
86 -6. ะžะฑั€ะฐะฑะฐั‚ั‹ะฒะฐั‚ัŒ ะดะฐะฝะฝั‹ะต ะฒ ะบะพะฝั‚ั€ะพะปะปะตั€ะต.  
87 - 1. ะŸะพัะปะต ัะพะทะดะฐะฝะธั/ะฟะพะธัะบะฐ {Table} ัะพะทะดะฐะตะผ/ะฝะฐั…ะพะดะธะผ ัะทั‹ะบะพะฒั‹ะต ะผะพะดะตะปะธ {Table}->generateLangs()  
88 - 2. ะŸั€ะธ POST ะทะฐะฟั€ะพัะต ะทะฐะณั€ัƒะถะฐะตะผ ะดะฐะฝะฝั‹ะต ะฒ ัะทั‹ะบะพะฒั‹ะต ะผะพะดะตะปะธ {Table}->loadLangs(Request $request)  
89 - 3. ะŸะพัะปะต ัะพั…ั€ะฐะฝะตะฝะธั, ะตัะปะธ ั‚ั€ะฐะฝะทะฐะฝะบั†ะธั ัƒัะฟะตัˆะฝะฐ, ั‚ะพ ัะฒะพะนัั‚ะฒะพ {Table}->transactionStatus ะฑัƒะดะตั‚ true, ะธะฝะฐั‡ะต ะฒะพะทะฝะธะบะปะฐ ะพัˆะธะฑะบะฐ ะฒ ะบะฐะบะพะน ั‚ะพ ะผะพะดะตะปะธ.  
90 -7. ะŸะพะปัƒั‡ะฐั‚ัŒ ะดะฐะฝะฝั‹ะต ะฝะฐ ะฟัƒะฑะปะธั‡ะฝะพะน ั‡ะฐัั‚ะธ ัะฐะนั‚ะฐ ั‡ะตั€ะตะท {Table}->lang.  
artbox-language/widgets/LanguageForm.php deleted
1 -<?php  
2 -  
3 - namespace artweb\artbox\language\widgets;  
4 -  
5 - use artweb\artbox\language\models\Language;  
6 - use yii\base\InvalidConfigException;  
7 - use yii\bootstrap\Widget;  
8 - use yii\db\ActiveRecord;  
9 - use yii\widgets\ActiveForm;  
10 -  
11 - class LanguageForm extends Widget  
12 - {  
13 -  
14 - /**  
15 - * @var ActiveRecord[] $modelLangs  
16 - */  
17 - public $modelLangs = [];  
18 -  
19 - /**  
20 - * @var string $formView  
21 - */  
22 - public $formView;  
23 -  
24 - /**  
25 - * @var string $idPrefix  
26 - */  
27 - public $idPrefix = 'lang';  
28 -  
29 - /**  
30 - * @var ActiveForm $form  
31 - */  
32 - private $form;  
33 -  
34 - /**  
35 - * @var Language[] $languages  
36 - */  
37 - private $languages = [];  
38 -  
39 - public function init()  
40 - {  
41 - parent::init();  
42 - if($this->formView === NULL) {  
43 - throw new InvalidConfigException('Form view must be set');  
44 - }  
45 - if(empty( $this->modelLangs ) || !is_array($this->modelLangs)) {  
46 - throw new InvalidConfigException('Language models must be passed');  
47 - }  
48 - if(empty( $this->getForm() )) {  
49 - throw new InvalidConfigException('Form model must be set');  
50 - }  
51 - $this->languages = Language::find()  
52 - ->where([ 'status' => true ])  
53 - ->orderBy([ 'default' => SORT_DESC ])  
54 - ->indexBy('id')  
55 - ->all();  
56 - }  
57 -  
58 - public function run()  
59 - {  
60 - return $this->render('language_form_frame', [  
61 - 'languages' => $this->languages,  
62 - 'form_view' => $this->formView,  
63 - 'modelLangs' => $this->modelLangs,  
64 - 'form' => $this->getForm(),  
65 - 'idPrefix' => $this->idPrefix,  
66 - ]);  
67 - }  
68 -  
69 - public function getForm(): ActiveForm  
70 - {  
71 - return $this->form;  
72 - }  
73 -  
74 - public function setForm(ActiveForm $value)  
75 - {  
76 - $this->form = $value;  
77 - }  
78 - }  
79 \ No newline at end of file 0 \ No newline at end of file
artbox-language/widgets/LanguagePicker.php deleted
1 -<?php  
2 -  
3 - namespace artweb\artbox\language\widgets;  
4 -  
5 - use artweb\artbox\language\models\Language;  
6 - use yii\bootstrap\Widget;  
7 -  
8 - class LanguagePicker extends Widget  
9 - {  
10 -  
11 - public function init()  
12 - {  
13 -  
14 - }  
15 -  
16 - public function run()  
17 - {  
18 - return $this->render('view', [  
19 - 'current' => Language::getCurrent(),  
20 - 'languages' => Language::find()  
21 - ->where([  
22 - '!=',  
23 - 'id',  
24 - Language::getCurrent()->id,  
25 - ])  
26 - ->all(),  
27 - ]);  
28 - }  
29 - }  
30 \ No newline at end of file 0 \ No newline at end of file
artbox-language/widgets/views/language_form_frame.php deleted
1 -<?php  
2 - use artweb\artbox\language\models\Language;  
3 - use yii\db\ActiveRecord;  
4 - use yii\helpers\Html;  
5 - use yii\web\View;  
6 - use yii\widgets\ActiveForm;  
7 -  
8 - /**  
9 - * @var Language[] $languages  
10 - * @var string $form_view  
11 - * @var ActiveRecord $modelLangs  
12 - * @var ActiveForm $form  
13 - * @var View $this  
14 - * @var string $idPrefix  
15 - */  
16 -?>  
17 -<div>  
18 - <?php  
19 - if(count($languages) > 1) {  
20 - ?>  
21 - <ul class="nav nav-tabs text-uppercase">  
22 - <?php  
23 - $first = true;  
24 - foreach($modelLangs as $lang => $model_lang) {  
25 - if(!array_key_exists($lang, $languages)) {  
26 - continue;  
27 - }  
28 - echo Html::tag('li', Html::a($languages[ $lang ]->url, [  
29 - '',  
30 - '#' => $idPrefix . '_' . $lang,  
31 - ], [ 'data-toggle' => 'tab' ]), [  
32 - 'class' => $first ? 'active' : '',  
33 - ]);  
34 - $first = false;  
35 - }  
36 - ?>  
37 - </ul>  
38 - <div class="tab-content">  
39 - <?php  
40 - $first = true;  
41 - foreach($modelLangs as $lang => $model_lang) {  
42 - if(!array_key_exists($lang, $languages)) {  
43 - continue;  
44 - }  
45 - echo Html::tag('div', $this->render($form_view, [  
46 - 'model_lang' => $model_lang,  
47 - 'language' => $languages[ $lang ],  
48 - 'form' => $form,  
49 - ]), [  
50 - 'class' => 'tab-pane' . ( $first ? ' active' : '' ),  
51 - 'id' => $idPrefix . '_' . $lang,  
52 - ]);  
53 - $first = false;  
54 - }  
55 - ?>  
56 - </div>  
57 - <?php  
58 - } else {  
59 - $language = current($languages);  
60 - if(isset( $modelLangs[ $language->id ] )) {  
61 - echo $this->render($form_view, [  
62 - 'model_lang' => $modelLangs[ $language->id ],  
63 - 'language' => $language,  
64 - 'form' => $form,  
65 - ]);  
66 - }  
67 - }  
68 - ?>  
69 -</div>  
artbox-language/widgets/views/view.php deleted
1 -<?php  
2 - use artweb\artbox\language\components\LanguageRequest;  
3 - use artweb\artbox\language\models\Language;  
4 - use yii\bootstrap\Html;  
5 -  
6 - /**  
7 - * @var Language $current Current language  
8 - * @var Language[] $languages Available languages  
9 - */  
10 -?>  
11 -<div id="language_picker">  
12 - <span id="current_language">  
13 - <?php  
14 - echo $current->name;  
15 - ?>  
16 - <span class="show-more-language">โ–ผ</span>  
17 - </span>  
18 - <ul id="languages">  
19 - <?php  
20 - foreach($languages as $language) {  
21 - ?>  
22 - <li class="item-language">  
23 - <?php  
24 - /**  
25 - * @var LanguageRequest $request  
26 - */  
27 - $request = \Yii::$app->getRequest();  
28 - echo Html::a($language->name, '/' . $language->url . $request->getLanguageUrl());  
29 - ?>  
30 - </li>  
31 - <?php  
32 - }  
33 - ?>  
34 - </ul>  
35 -</div>  
artbox-seo/composer.json deleted
1 -{  
2 - "name": "artweb/artbox-seo",  
3 - "description": "Yii2 light-weight CMS",  
4 - "license": "BSD-3-Clause",  
5 - "require": {  
6 - "php": ">=7.0",  
7 - "yiisoft/yii2": "*",  
8 - "developeruz/yii2-db-rbac": "*"  
9 - },  
10 - "autoload": {  
11 - "psr-4": {  
12 - "artweb\\artbox\\seo\\": ""  
13 - }  
14 - }  
15 -}  
16 \ No newline at end of file 0 \ No newline at end of file
artbox-ecommerce/behaviors/FilterBehavior.php renamed to behaviors/FilterBehavior.php
artbox-ecommerce/composer.json renamed to composer.json
artbox-ecommerce/config.php renamed to config.php
artbox-ecommerce/controllers/ManageController.php renamed to controllers/ManageController.php
artbox-ecommerce/controllers/ProductUnitController.php renamed to controllers/ProductUnitController.php
artbox-ecommerce/controllers/TaxGroupController.php renamed to controllers/TaxGroupController.php
artbox-ecommerce/controllers/TaxOptionController.php renamed to controllers/TaxOptionController.php
artbox-ecommerce/controllers/VariantController.php renamed to controllers/VariantController.php
artbox-ecommerce/helpers/FilterHelper.php renamed to helpers/FilterHelper.php
artbox-ecommerce/helpers/ProductHelper.php renamed to helpers/ProductHelper.php
artbox-ecommerce/models/Brand.php renamed to models/Brand.php
artbox-ecommerce/models/BrandLang.php renamed to models/BrandLang.php
artbox-ecommerce/models/BrandSearch.php renamed to models/BrandSearch.php
artbox-ecommerce/models/Category.php renamed to models/Category.php
artbox-ecommerce/models/CategoryLang.php renamed to models/CategoryLang.php
artbox-ecommerce/models/CategoryQuery.php renamed to models/CategoryQuery.php
artbox-ecommerce/models/CategorySearch.php renamed to models/CategorySearch.php
artbox-ecommerce/models/Export.php renamed to models/Export.php
artbox-ecommerce/models/Import.php renamed to models/Import.php
artbox-ecommerce/models/Product.php renamed to models/Product.php
artbox-ecommerce/models/ProductCategory.php renamed to models/ProductCategory.php
artbox-ecommerce/models/ProductImage.php renamed to models/ProductImage.php
artbox-ecommerce/models/ProductLang.php renamed to models/ProductLang.php
artbox-ecommerce/models/ProductOption.php renamed to models/ProductOption.php
artbox-ecommerce/models/ProductSearch.php renamed to models/ProductSearch.php
artbox-ecommerce/models/ProductStock.php renamed to models/ProductStock.php
artbox-ecommerce/models/ProductUnit.php renamed to models/ProductUnit.php
artbox-ecommerce/models/ProductUnitLang.php renamed to models/ProductUnitLang.php
artbox-ecommerce/models/ProductUnitSearch.php renamed to models/ProductUnitSearch.php
artbox-ecommerce/models/ProductVariant.php renamed to models/ProductVariant.php
artbox-ecommerce/models/ProductVariantLang.php renamed to models/ProductVariantLang.php
artbox-ecommerce/models/ProductVariantOption.php renamed to models/ProductVariantOption.php
artbox-ecommerce/models/ProductVariantSearch.php renamed to models/ProductVariantSearch.php
artbox-ecommerce/models/Stock.php renamed to models/Stock.php
artbox-ecommerce/models/StockLang.php renamed to models/StockLang.php
artbox-ecommerce/models/TaxGroup.php renamed to models/TaxGroup.php
artbox-ecommerce/models/TaxGroupLang.php renamed to models/TaxGroupLang.php
artbox-ecommerce/models/TaxGroupSearch.php renamed to models/TaxGroupSearch.php
artbox-ecommerce/models/TaxGroupToCategory.php renamed to models/TaxGroupToCategory.php
artbox-ecommerce/models/TaxOption.php renamed to models/TaxOption.php
artbox-ecommerce/models/TaxOptionLang.php renamed to models/TaxOptionLang.php
artbox-ecommerce/models/TaxOptionSearch.php renamed to models/TaxOptionSearch.php
artbox-ecommerce/views/manage/_form.php renamed to views/manage/_form.php
artbox-ecommerce/views/manage/_form_language.php renamed to views/manage/_form_language.php
artbox-ecommerce/views/manage/create.php renamed to views/manage/create.php
artbox-ecommerce/views/manage/export-process.php renamed to views/manage/export-process.php
artbox-ecommerce/views/manage/export.php renamed to views/manage/export.php
artbox-ecommerce/views/manage/import-process.php renamed to views/manage/import-process.php
artbox-ecommerce/views/manage/import.php renamed to views/manage/import.php
artbox-ecommerce/views/manage/index.php renamed to views/manage/index.php
artbox-ecommerce/views/manage/update.php renamed to views/manage/update.php