caboose-cms 0.7.42 → 0.7.43
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/caboose/media_browser.js +280 -0
- data/app/assets/javascripts/caboose/model/bound_media_image.js +140 -0
- data/app/controllers/caboose/login_controller.rb +2 -2
- data/app/controllers/caboose/products_controller.rb +3 -0
- data/app/controllers/caboose/variants_controller.rb +29 -0
- data/app/models/caboose/authenticator.rb +2 -2
- data/app/models/caboose/comment_routes.rb +94 -7
- data/app/models/caboose/product.rb +22 -1
- data/app/models/caboose/schema.rb +10 -2
- data/app/models/caboose/variant.rb +12 -1
- data/app/views/caboose/login_mailer/forgot_password_email.html.erb +5 -3
- data/app/views/caboose/products/admin_edit_options.html.erb +15 -9
- data/app/views/caboose/variants/admin_edit.html.erb +8 -4
- data/app/views/caboose/variants/admin_edit_option1_media.html.erb +94 -0
- data/app/views/caboose/variants/admin_edit_option2_media.html.erb +94 -0
- data/app/views/caboose/variants/admin_edit_option3_media.html.erb +94 -0
- data/app/views/caboose/variants/admin_edit_sort_order.html.erb +58 -4
- data/app/views/caboose/variants/admin_index.html.erb +32 -29
- data/app/views/caboose/variants/admin_new.html.erb +4 -2
- data/config/routes.rb +7 -0
- data/lib/caboose.rb +3 -0
- data/lib/caboose/version.rb +1 -1
- data/lib/tasks/caboose.rake +10 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dab3266d8c95bbdef871f2dc1d8cc2ec5658e62a
|
4
|
+
data.tar.gz: 278ff6700254daf5770925e589dc8958207cbe48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92c6aec06acb45efbf1fe27ec7bde8dd476dcc28da9e5d7930b05dbc79d6aabb26f6e4a72d8832966919ea37ad4232e073f8b35c210165486a89685336486d1c
|
7
|
+
data.tar.gz: ab7f88af93d1d150323e43fd6197305c95c92c6cbe35b0cdfb83c71852e0dd8429db63014d0842aaddc4c1febfb7f437ff4aed977a99323699424a1e2804dbbd
|
@@ -0,0 +1,280 @@
|
|
1
|
+
|
2
|
+
var MediaBrowser = function(params) { this.init(params); };
|
3
|
+
|
4
|
+
MediaBrowser.prototype = {
|
5
|
+
|
6
|
+
media_id: false,
|
7
|
+
top_cat_id: false,
|
8
|
+
cat: false,
|
9
|
+
cat_id: false,
|
10
|
+
categories: false,
|
11
|
+
s3_upload_url: false,
|
12
|
+
aws_access_key_id: false,
|
13
|
+
policy: false,
|
14
|
+
signature: false,
|
15
|
+
selected_media: false,
|
16
|
+
uploader: false,
|
17
|
+
refresh_unprocessed_images: false,
|
18
|
+
upload_extensions: "jpg,jpeg,png,gif,tif,tiff,pdf,doc,docx,odt,odp,ods,ppt,pptx,xls,xlsx,zip,tgz,csv,txt",
|
19
|
+
file_view: 'thumbnail',
|
20
|
+
|
21
|
+
init: function(params) {
|
22
|
+
var that = this;
|
23
|
+
for (var i in params)
|
24
|
+
this[i] = params[i];
|
25
|
+
|
26
|
+
$("#uploader")
|
27
|
+
.empty()
|
28
|
+
.append($('<div/>').attr('id', 'the_uploader'));
|
29
|
+
that.refresh();
|
30
|
+
},
|
31
|
+
|
32
|
+
refresh: function()
|
33
|
+
{
|
34
|
+
var that = this;
|
35
|
+
that.refresh_categories(function() {
|
36
|
+
that.refresh_media();
|
37
|
+
});
|
38
|
+
that.print_controls();
|
39
|
+
},
|
40
|
+
|
41
|
+
toggle_uploader: function()
|
42
|
+
{
|
43
|
+
var that = this;
|
44
|
+
if (that.uploader)
|
45
|
+
{
|
46
|
+
$("#the_uploader").slideUp(400, function() {
|
47
|
+
$("#the_uploader").plupload('destroy');
|
48
|
+
that.uploader = false;
|
49
|
+
});
|
50
|
+
}
|
51
|
+
else
|
52
|
+
{
|
53
|
+
$("#the_uploader").hide();
|
54
|
+
that.uploader = $("#the_uploader").plupload({
|
55
|
+
runtimes: 'html5,flash,silverlight',
|
56
|
+
url: that.s3_upload_url,
|
57
|
+
multipart: true,
|
58
|
+
multipart_params: {
|
59
|
+
key: that.cat_id + '_${filename}', // use filename as a key
|
60
|
+
Filename: that.cat_id + '_${filename}', // adding this to keep consistency across the runtimes
|
61
|
+
acl: 'public-read',
|
62
|
+
//'Content-Type': 'image/jpeg',
|
63
|
+
AWSAccessKeyId: that.aws_access_key_id,
|
64
|
+
policy: that.policy,
|
65
|
+
signature: that.signature
|
66
|
+
},
|
67
|
+
file_data_name: 'file', // optional, but better be specified directly
|
68
|
+
filters: {
|
69
|
+
max_file_size: '100mb', // Maximum file size
|
70
|
+
mime_types: [{ title: "Upload files", extensions: that.upload_extensions }] // Specify what files to browse for
|
71
|
+
},
|
72
|
+
flash_swf_url: '../../js/Moxie.swf', // Flash settings
|
73
|
+
silverlight_xap_url: '../../js/Moxie.xap', // Silverlight settings
|
74
|
+
init: {
|
75
|
+
BeforeUpload: function(up, file) {
|
76
|
+
$.ajax({
|
77
|
+
url: '/admin/media/pre-upload',
|
78
|
+
type: 'post',
|
79
|
+
data: {
|
80
|
+
media_category_id: that.cat_id,
|
81
|
+
name: file.name
|
82
|
+
},
|
83
|
+
success: function(resp) {},
|
84
|
+
async: false
|
85
|
+
});
|
86
|
+
controller.refresh();
|
87
|
+
},
|
88
|
+
FileUploaded: function(ip, file)
|
89
|
+
{
|
90
|
+
that.refresh();
|
91
|
+
},
|
92
|
+
UploadComplete: function(up, files) {
|
93
|
+
that.refresh();
|
94
|
+
if (that.uploader)
|
95
|
+
{
|
96
|
+
$("#the_uploader").slideUp(400, function() {
|
97
|
+
$("#the_uploader").plupload('destroy');
|
98
|
+
that.uploader = false;
|
99
|
+
});
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
});
|
104
|
+
$("#the_uploader").slideDown();
|
105
|
+
}
|
106
|
+
},
|
107
|
+
|
108
|
+
refresh_categories: function(after)
|
109
|
+
{
|
110
|
+
var that = this;
|
111
|
+
$.ajax({
|
112
|
+
url: '/admin/media-categories/flat-tree',
|
113
|
+
type: 'get',
|
114
|
+
async: false,
|
115
|
+
success: function(resp) {
|
116
|
+
that.categories = resp;
|
117
|
+
if (!that.cat_id)
|
118
|
+
that.cat_id = that.categories[0].id;
|
119
|
+
that.print_categories();
|
120
|
+
if (after) after();
|
121
|
+
}
|
122
|
+
});
|
123
|
+
},
|
124
|
+
|
125
|
+
refresh_media: function()
|
126
|
+
{
|
127
|
+
var that = this;
|
128
|
+
$.ajax({
|
129
|
+
url: '/admin/media/json',
|
130
|
+
type: 'get',
|
131
|
+
async: false,
|
132
|
+
data: { media_category_id: that.cat_id },
|
133
|
+
success: function(resp) {
|
134
|
+
that.cat = resp;
|
135
|
+
that.cat_id = that.cat.id;
|
136
|
+
that.selected_media = [];
|
137
|
+
that.print_media();
|
138
|
+
}
|
139
|
+
});
|
140
|
+
},
|
141
|
+
|
142
|
+
print_categories: function()
|
143
|
+
{
|
144
|
+
var that = this;
|
145
|
+
var ul = $('<ul/>');
|
146
|
+
if (that.categories.length > 0)
|
147
|
+
{
|
148
|
+
$.each(that.categories, function(i, cat) {
|
149
|
+
var li = $('<li/>')
|
150
|
+
.addClass('category')
|
151
|
+
.attr('id', 'cat' + cat.id)
|
152
|
+
.data('media_category_id', cat.id)
|
153
|
+
.append($('<a/>').attr('href', '#').html(cat.name + ' (' + cat.media_count + ')').click(function(e) { e.preventDefault(); that.select_category($(this).parent().data('media_category_id')); }));
|
154
|
+
if (cat.id == that.cat_id)
|
155
|
+
li.addClass('selected');
|
156
|
+
ul.append(li);
|
157
|
+
});
|
158
|
+
}
|
159
|
+
else
|
160
|
+
ul = $('<p/>').html("There are no media categories.");
|
161
|
+
$('#categories').empty().append(ul);
|
162
|
+
},
|
163
|
+
|
164
|
+
print_controls: function()
|
165
|
+
{
|
166
|
+
var that = this;
|
167
|
+
$('#controls').empty()
|
168
|
+
//.append($('<p/>').append($('<a/>').attr('href', '#').html('New Category').click(function(e) { e.preventDefault(); that.add_category(); })))
|
169
|
+
//.append($('<div/>').attr('id', 'new_cat_message'))
|
170
|
+
//.append($('<p/>').append($('<a/>').attr('href', '#').html('Upload').click(function(e) { e.preventDefault(); that.toggle_uploader(); })))
|
171
|
+
//.append($('<p/>').append($('<a/>').attr('href', '#').html('Toggle Thumbnail/List View').click(function(e) { e.preventDefault(); that.toggle_file_view(); })));
|
172
|
+
.append($('<p/>')
|
173
|
+
.append($('<a/>').attr('href', '#').html('New Category').click(function(e) { e.preventDefault(); that.add_category(); })).append(' | ')
|
174
|
+
.append($('<a/>').attr('href', '#').html('Upload to this Category' ).click(function(e) { e.preventDefault(); that.toggle_uploader(); })).append(' | ')
|
175
|
+
.append($('<a/>').attr('href', '#').html(that.file_view == 'thumbnail' ? 'List View' : 'Thumbnail View').click(function(e) { e.preventDefault(); that.toggle_file_view(); }))
|
176
|
+
)
|
177
|
+
.append($('<div/>').attr('id', 'new_cat_message'));
|
178
|
+
},
|
179
|
+
|
180
|
+
print_media: function()
|
181
|
+
{
|
182
|
+
var that = this;
|
183
|
+
var ul = $('<ul/>').addClass(that.file_view + '_view');
|
184
|
+
var processing = false;
|
185
|
+
var d = new Date();
|
186
|
+
d = d.getTime();
|
187
|
+
|
188
|
+
if (that.cat.media.length > 0)
|
189
|
+
{
|
190
|
+
$.each(that.cat.media, function(i, m) {
|
191
|
+
if (m.media_type == 'image' && m.processed == false)
|
192
|
+
processing = true
|
193
|
+
var li = $('<li/>')
|
194
|
+
.attr('id', 'media' + m.id)
|
195
|
+
.addClass('media')
|
196
|
+
.data('media_id', m.id)
|
197
|
+
.click(function(e) { that.select_media(that, $(this).data('media_id')); })
|
198
|
+
.append($('<span/>').addClass('name').html(m.original_name));
|
199
|
+
if (m.image_urls)
|
200
|
+
li.append($('<img/>').attr('src', m.image_urls.tiny_url + '?' + d));
|
201
|
+
//if (that.selected_media.indexOf(m.id) > -1)
|
202
|
+
// li.addClass('selected ui-selected');
|
203
|
+
if (m.id == that.media_id)
|
204
|
+
li.addClass('selected ui-selected');
|
205
|
+
ul.append(li);
|
206
|
+
});
|
207
|
+
}
|
208
|
+
else
|
209
|
+
ul = $('<p/>').html("This category is empty.");
|
210
|
+
$('#media').empty().append(ul);
|
211
|
+
if (that.refresh_unprocessed_images == true && processing)
|
212
|
+
setTimeout(function() { that.refresh(); }, 2000);
|
213
|
+
if (modal)
|
214
|
+
modal.autosize();
|
215
|
+
|
216
|
+
$.each(that.cat.media, function(i, m) {
|
217
|
+
$('li.media').draggable({
|
218
|
+
multiple: true,
|
219
|
+
revert: 'invalid',
|
220
|
+
start: function() { $(this).data("origPosition", $(this).position()); }
|
221
|
+
});
|
222
|
+
});
|
223
|
+
},
|
224
|
+
|
225
|
+
//============================================================================
|
226
|
+
|
227
|
+
select_media: function(browser, media_id) {},
|
228
|
+
|
229
|
+
//============================================================================
|
230
|
+
|
231
|
+
select_category: function(cat_id)
|
232
|
+
{
|
233
|
+
var that = this;
|
234
|
+
that.cat_id = cat_id;
|
235
|
+
that.print_categories();
|
236
|
+
that.refresh_media();
|
237
|
+
},
|
238
|
+
|
239
|
+
add_category: function(name)
|
240
|
+
{
|
241
|
+
var that = this;
|
242
|
+
if (!name)
|
243
|
+
{
|
244
|
+
if (!$('#new_cat_message').is(':empty'))
|
245
|
+
{
|
246
|
+
$('#new_cat_message').empty();
|
247
|
+
return;
|
248
|
+
}
|
249
|
+
var div = $('<p/>').addClass('note warning')
|
250
|
+
.append('Name: ')
|
251
|
+
.append($('<input/>').attr('type', 'text').attr('id', 'new_cat_name')).append(" ")
|
252
|
+
.append($('<input/>').attr('type', 'button').val('Add').click(function() { that.add_category($('#new_cat_name').val()); })).append(" ")
|
253
|
+
.append($('<input/>').attr('type', 'button').val('Cancel').click(function() { $('#new_cat_message').empty(); }));
|
254
|
+
$('#new_cat_message').empty().append(div);
|
255
|
+
return;
|
256
|
+
}
|
257
|
+
$('#new_cat_message').empty().html("<p class='loading'>Adding category...</p>");
|
258
|
+
$.ajax({
|
259
|
+
url: '/admin/media-categories',
|
260
|
+
type: 'post',
|
261
|
+
data: {
|
262
|
+
parent_id: that.cat.id,
|
263
|
+
name: name
|
264
|
+
},
|
265
|
+
success: function(resp) {
|
266
|
+
if (resp.error) $('#new_cat_message').empty().html("<p class='note error'>" + resp.error + "</p>");
|
267
|
+
if (resp.refresh) { that.cat_id = resp.new_id; that.refresh(); }
|
268
|
+
}
|
269
|
+
});
|
270
|
+
},
|
271
|
+
|
272
|
+
toggle_file_view: function()
|
273
|
+
{
|
274
|
+
var that = this;
|
275
|
+
that.file_view = (that.file_view == 'thumbnail' ? 'list' : 'thumbnail');
|
276
|
+
that.print_controls();
|
277
|
+
that.print_media();
|
278
|
+
},
|
279
|
+
|
280
|
+
};
|
@@ -0,0 +1,140 @@
|
|
1
|
+
|
2
|
+
BoundMediaImage = BoundControl.extend({
|
3
|
+
|
4
|
+
//el: false,
|
5
|
+
//model: false,
|
6
|
+
//attribute: false,
|
7
|
+
//binder: false,
|
8
|
+
|
9
|
+
width: 100,
|
10
|
+
style: 'medium',
|
11
|
+
authenticity_token: false,
|
12
|
+
|
13
|
+
init: function(params) {
|
14
|
+
for (var thing in params)
|
15
|
+
this[thing] = params[thing];
|
16
|
+
|
17
|
+
this.el = this.el ? this.el : this.model.name.toLowerCase() + '_' + this.model.id + '_' + this.attribute.name;
|
18
|
+
|
19
|
+
if (!this.attribute.update_url)
|
20
|
+
this.attribute.update_url = this.model.update_url;
|
21
|
+
|
22
|
+
var this2 = this;
|
23
|
+
$('#'+this.el).wrap($('<div/>')
|
24
|
+
.attr('id', this.el + '_container')
|
25
|
+
.addClass('mb_container')
|
26
|
+
.css('position', 'relative')
|
27
|
+
);
|
28
|
+
$('#'+this.el+'_container').empty();
|
29
|
+
|
30
|
+
$('#'+this.el+'_container').append($('<img/>')
|
31
|
+
.attr('src', this.attribute.value)
|
32
|
+
.css('width', this.width)
|
33
|
+
.css('float', 'left')
|
34
|
+
.css('margin-right', 10)
|
35
|
+
);
|
36
|
+
$('#'+this.el+'_container')
|
37
|
+
.append($('<form target="' + this.el + '_iframe"></form>')
|
38
|
+
.attr('id', this.el + '_form')
|
39
|
+
.attr('action', this.attribute.update_url)
|
40
|
+
.attr('method', 'post')
|
41
|
+
.attr('enctype', 'multipart/form-data')
|
42
|
+
.attr('encoding', 'multipart/form-data')
|
43
|
+
//.attr('target', this.el + '_iframe')
|
44
|
+
.on('submit', function() {
|
45
|
+
$('#'+this2.el+'_message').html("<p class='loading'>Uploading...</p>");
|
46
|
+
$('#'+this2.el+'_iframe').on('load', function() { this2.post_upload(); });
|
47
|
+
return true;
|
48
|
+
})
|
49
|
+
.append($('<input/>').attr('type', 'hidden').attr('name', 'authenticity_token').val(this.binder.authenticity_token))
|
50
|
+
.append($('<div/>')
|
51
|
+
.attr('id', this.el + '_fake_file_input')
|
52
|
+
.addClass('mb_fake_file_input')
|
53
|
+
.append($('<input/>')
|
54
|
+
.attr('type', 'button')
|
55
|
+
.attr('id', this.el + '_update_button')
|
56
|
+
.val('Update ' + this.attribute.nice_name)
|
57
|
+
.click(function() { $('#'+this2.el+'_file').click(); })
|
58
|
+
)
|
59
|
+
.append($('<input/>')
|
60
|
+
.attr('type', 'file')
|
61
|
+
.attr('id', this.el + '_file')
|
62
|
+
.attr('name', this.attribute.name)
|
63
|
+
.change(function() { $('#'+this2.el+'_form').trigger('submit'); })
|
64
|
+
)
|
65
|
+
.append($('<input/>')
|
66
|
+
.attr('type', 'submit')
|
67
|
+
.val('Submit')
|
68
|
+
)
|
69
|
+
)
|
70
|
+
);
|
71
|
+
$('#'+this.el+'_container').append($('<div/>')
|
72
|
+
.attr('id', this.el + '_message')
|
73
|
+
);
|
74
|
+
iframe = $("<iframe name=\"" + this.el + "_iframe\" id=\"" + this.el + "_iframe\" src=''></iframe>");
|
75
|
+
if (this.attribute.debug)
|
76
|
+
iframe.css('width', '100%').css('height', 600).css('background', '#fff');
|
77
|
+
else
|
78
|
+
iframe.css('width', 0).css('height', 0).css('border', 0);
|
79
|
+
$('#'+this.el+'_container').append(iframe);
|
80
|
+
$('#'+this.el+'_container').append($('<br/>').css('clear', 'both'));
|
81
|
+
|
82
|
+
var w = $('#' + this.el + '_update_button').outerWidth(true);
|
83
|
+
$('#' + this.el + '_fake_file_input').css('width', '' + w + 'px');
|
84
|
+
},
|
85
|
+
|
86
|
+
post_upload: function() {
|
87
|
+
$('#'+this.el+'_message').empty();
|
88
|
+
|
89
|
+
var str = frames[this.el+'_iframe'].document.documentElement.innerHTML;
|
90
|
+
str = str.replace(/[\s\S]*?{([\s\S]*?)/, '{$1');
|
91
|
+
str = str.substr(0, str.lastIndexOf('}')+1);
|
92
|
+
var resp = $.parseJSON(str);
|
93
|
+
if (resp.success)
|
94
|
+
{
|
95
|
+
if (resp.attributes && resp.attributes[this.attribute.name])
|
96
|
+
for (var thing in resp.attributes[this.attribute.name])
|
97
|
+
this.attribute[thing] = resp.attributes[this.attribute.name][thing];
|
98
|
+
this.attribute.value_clean = this.attribute.value;
|
99
|
+
}
|
100
|
+
|
101
|
+
if (resp.error)
|
102
|
+
this.error(resp.error);
|
103
|
+
else
|
104
|
+
{
|
105
|
+
if (this.attribute.image_refresh_delay)
|
106
|
+
{
|
107
|
+
var that = this;
|
108
|
+
setTimeout(function() { that.refresh_image(); }, this.attribute.image_refresh_delay);
|
109
|
+
}
|
110
|
+
else
|
111
|
+
{
|
112
|
+
this.refresh_image();
|
113
|
+
}
|
114
|
+
}
|
115
|
+
},
|
116
|
+
|
117
|
+
refresh_image: function() {
|
118
|
+
var src = this.attribute.value;
|
119
|
+
if (src.indexOf('?') > 0)
|
120
|
+
src = src.split('?')[0];
|
121
|
+
src = src + '?' + Math.random();
|
122
|
+
$('#'+this.el+'_container img').attr('src', src);
|
123
|
+
},
|
124
|
+
|
125
|
+
error: function(str) {
|
126
|
+
if (!$('#'+this.el+'_message').length)
|
127
|
+
{
|
128
|
+
$('#'+this.el+'_container').append($('<div/>')
|
129
|
+
.attr('id', this.el + '_message')
|
130
|
+
.css('width', $('#'+this.el).outerWidth())
|
131
|
+
);
|
132
|
+
}
|
133
|
+
$('#'+this.el+'_message').hide();
|
134
|
+
$('#'+this.el+'_message').html("<p class='note error'>" + str + "</p>");
|
135
|
+
$('#'+this.el+'_message').slideDown();
|
136
|
+
var this2 = this;
|
137
|
+
setTimeout(function() { $('#'+this2.el+'_message').slideUp(function() { $(this).empty(); }); }, 3000);
|
138
|
+
}
|
139
|
+
|
140
|
+
});
|
@@ -83,8 +83,8 @@ module Caboose
|
|
83
83
|
bob.password_reset_id = rand
|
84
84
|
bob.password_reset_sent = DateTime.now
|
85
85
|
bob.save
|
86
|
-
|
87
|
-
LoginMailer.forgot_password_email(bob).deliver
|
86
|
+
|
87
|
+
LoginMailer.configure_for_site(@site.id).forgot_password_email(bob).deliver
|
88
88
|
|
89
89
|
resp.success = "We just sent you an email. The reset link inside is good for 3 days."
|
90
90
|
render :json => resp
|
@@ -381,6 +381,9 @@ module Caboose
|
|
381
381
|
when 'option1' then product.option1 = value
|
382
382
|
when 'option2' then product.option2 = value
|
383
383
|
when 'option3' then product.option3 = value
|
384
|
+
when 'option1_media' then product.option1_media = value
|
385
|
+
when 'option2_media' then product.option2_media = value
|
386
|
+
when 'option3_media' then product.option3_media = value
|
384
387
|
when 'default1'
|
385
388
|
product.default1 = value
|
386
389
|
Variant.where(:product_id => product.id, :option1 => nil).each do |p|
|