liquid_feedback_frontend
changeset 1495:17e7082c377a
Added image attachments for initiatives
author | bsw |
---|---|
date | Mon Feb 10 21:10:49 2020 +0100 (2020-02-10) |
parents | 3e9b0f1adec3 |
children | ed3c40911ae1 |
files | app/main/_filter/21_auth.lua app/main/draft/_action/add.lua app/main/draft/new.lua app/main/draft/show.lua app/main/draft/show_file_upload.lua app/main/file/show.jpg.lua app/main/initiative/show.lua model/draft.lua model/draft_attachment.lua model/file.lua |
line diff
1.1 --- a/app/main/_filter/21_auth.lua Mon Dec 09 15:54:57 2019 +0100 1.2 +++ b/app/main/_filter/21_auth.lua Mon Feb 10 21:10:49 2020 +0100 1.3 @@ -71,6 +71,7 @@ 1.4 or module == "suggestion" and view == "show" 1.5 or module == "draft" and view == "diff" 1.6 or module == "draft" and view == "show" 1.7 + or module == "file" and view == "show.jpg" 1.8 or module == "index" and view == "search" 1.9 or module == "index" and view == "usage_terms" 1.10 or module == "help" and view == "introduction"
2.1 --- a/app/main/draft/_action/add.lua Mon Dec 09 15:54:57 2019 +0100 2.2 +++ b/app/main/draft/_action/add.lua Mon Feb 10 21:10:49 2020 +0100 2.3 @@ -21,7 +21,68 @@ 2.4 draft_text = abstract .. "<!--END_OF_ABSTRACT-->" .. draft_text 2.5 end 2.6 2.7 -return Draft:update_content( 2.8 +if config.attachments then 2.9 + local file_upload_session = param.get("file_upload_session") 2.10 + file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "") 2.11 + local file_uploads = json.array() 2.12 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json") 2.13 + local fh = io.open(filename, "r") 2.14 + if fh then 2.15 + file_uploads = json.import(fh:read("*a")) 2.16 + end 2.17 + for i, file_upload in ipairs(file_uploads) do 2.18 + if param.get("file_upload_delete_" .. file_upload.id, atom.boolean) then 2.19 + for j = i, #file_uploads - 1 do 2.20 + file_uploads[j] = file_uploads[j+1] 2.21 + end 2.22 + file_uploads[#file_uploads] = nil 2.23 + end 2.24 + end 2.25 + local convert_func = config.attachments.convert_func 2.26 + local last_id = param.get("file_upload_last_id", atom.number) 2.27 + if last_id and last_id > 0 then 2.28 + if last_id > 1024 then 2.29 + last_id = 1024 2.30 + end 2.31 + for i = 1, last_id do 2.32 + local file = param.get("file_" .. i) 2.33 + if file and #file > 0 then 2.34 + local id = multirand.string( 2.35 + 32, 2.36 + '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 2.37 + ) 2.38 + local data, err, status = convert_func(file) 2.39 + if status ~= 0 or data == nil then 2.40 + slot.put_into("error", _"Error while converting image. Please note, that only JPG files are supported!") 2.41 + return false 2.42 + end 2.43 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. id .. ".jpg") 2.44 + local fh = assert(io.open(filename, "w")) 2.45 + fh:write(file) 2.46 + fh:write("\n") 2.47 + fh:close() 2.48 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. id .. ".preview.jpg") 2.49 + local fh = assert(io.open(filename, "w")) 2.50 + fh:write(data) 2.51 + fh:write("\n") 2.52 + fh:close() 2.53 + table.insert(file_uploads, json.object{ 2.54 + id = id, 2.55 + filename = filename, 2.56 + title = param.get("title_" .. i), 2.57 + description = param.get("description_" .. i) 2.58 + }) 2.59 + end 2.60 + end 2.61 + end 2.62 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json") 2.63 + local fh = assert(io.open(filename, "w")) 2.64 + fh:write(json.export(file_uploads)) 2.65 + fh:write("\n") 2.66 + fh:close() 2.67 +end 2.68 + 2.69 +local draft_id = Draft:update_content( 2.70 app.session.member.id, 2.71 param.get("initiative_id", atom.integer), 2.72 param.get("formatting_engine"), 2.73 @@ -29,3 +90,66 @@ 2.74 nil, 2.75 param.get("preview") or param.get("edit") 2.76 ) 2.77 + 2.78 +if draft_id and config.attachments then 2.79 + local file_upload_session = param.get("file_upload_session") 2.80 + file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "") 2.81 + 2.82 + local draft_attachments = DraftAttachment:new_selector() 2.83 + :add_where{ "draft_attachment.draft_id = ?", draft_id } 2.84 + :exec() 2.85 + 2.86 + for i, draft_attachment in ipairs(draft_attachments) do 2.87 + if param.get("file_delete_" .. draft_attachment.file_id, atom.boolean) then 2.88 + draft_attachment:destroy() 2.89 + end 2.90 + end 2.91 + 2.92 + local file_uploads = json.array() 2.93 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json") 2.94 + local fh = io.open(filename, "r") 2.95 + if fh then 2.96 + file_uploads = json.import(fh:read("*a")) 2.97 + end 2.98 + for i, file_upload in ipairs(file_uploads) do 2.99 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. file_upload.id .. ".jpg") 2.100 + local data 2.101 + local fh = io.open(filename, "r") 2.102 + if fh then 2.103 + data = fh:read("*a") 2.104 + end 2.105 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. file_upload.id .. ".preview.jpg") 2.106 + local data_preview 2.107 + local fh = io.open(filename, "r") 2.108 + if fh then 2.109 + data_preview = fh:read("*a") 2.110 + end 2.111 + 2.112 + local hash = moonhash.sha3_512(data) 2.113 + 2.114 + local file = File:new_selector() 2.115 + :add_where{ "hash = ?", hash } 2.116 + :add_where{ "content_type = ?", "image/jpeg" } 2.117 + :optional_object_mode() 2.118 + :exec() 2.119 + 2.120 + if not file then 2.121 + file = File:new() 2.122 + file.content_type = "image/jpeg" 2.123 + file.hash = hash 2.124 + file.data = data 2.125 + file.preview_content_type = "image/jpeg" 2.126 + file.preview_data = data_preview 2.127 + file:save() 2.128 + end 2.129 + 2.130 + local draft_attachment = DraftAttachment:new() 2.131 + draft_attachment.draft_id = draft_id 2.132 + draft_attachment.file_id = file.id 2.133 + draft_attachment.title = file_upload.title 2.134 + draft_attachment.description = file_upload.description 2.135 + draft_attachment:save() 2.136 + end 2.137 +end 2.138 + 2.139 +return draft_id and true or false
3.1 --- a/app/main/draft/new.lua Mon Dec 09 15:54:57 2019 +0100 3.2 +++ b/app/main/draft/new.lua Mon Feb 10 21:10:49 2020 +0100 3.3 @@ -23,7 +23,7 @@ 3.4 3.5 ui.form{ 3.6 record = draft, 3.7 - attr = { class = "vertical section" }, 3.8 + attr = { class = "vertical section", enctype = 'multipart/form-data' }, 3.9 module = "draft", 3.10 action = "add", 3.11 params = { initiative_id = initiative.id }, 3.12 @@ -65,6 +65,54 @@ 3.13 } 3.14 slot.put("<br />") 3.15 3.16 + if config.attachments then 3.17 + local file_upload_session = param.get("file_upload_session") or multirand.string( 3.18 + 32, 3.19 + '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 3.20 + ) 3.21 + file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "") 3.22 + ui.field.hidden{ name = "file_upload_session", value = file_upload_session } 3.23 + local files = File:new_selector() 3.24 + :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id") 3.25 + :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id } 3.26 + :reset_fields() 3.27 + :add_field("file.id") 3.28 + :add_field("draft_attachment.title") 3.29 + :add_field("draft_attachment.description") 3.30 + :add_order_by("draft_attachment.id") 3.31 + :exec() 3.32 + 3.33 + if #files > 0 then 3.34 + ui.container { 3.35 + content = function() 3.36 + for i, file in ipairs(files) do 3.37 + if param.get("file_delete_" .. file.id, atom.boolean) then 3.38 + ui.field.hidden{ name = "file_delete_" .. file.id, value = "1" } 3.39 + else 3.40 + ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } } 3.41 + ui.container{ content = file.title or "" } 3.42 + ui.container{ content = file.description or "" } 3.43 + slot.put("<br /><br />") 3.44 + end 3.45 + end 3.46 + end 3.47 + } 3.48 + end 3.49 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json") 3.50 + local fh = io.open(filename, "r") 3.51 + if fh then 3.52 + local file_uploads = json.import(fh:read("*a")) 3.53 + for i, file_upload in ipairs(file_uploads) do 3.54 + ui.image{ module = "draft", view = "show_file_upload", params = { 3.55 + file_upload_session = file_upload_session, file_id = file_upload.id, preview = true 3.56 + } } 3.57 + ui.container{ content = file_upload.title or "" } 3.58 + ui.container{ content = file_upload.description or "" } 3.59 + slot.put("<br />") 3.60 + end 3.61 + end 3.62 + end 3.63 + 3.64 ui.tag{ 3.65 tag = "input", 3.66 attr = { 3.67 @@ -123,7 +171,71 @@ 3.68 else 3.69 ui.container { content = _"You cannot change your text again later, because this issue is already in verfication phase!" } 3.70 end 3.71 + 3.72 slot.put("<br />") 3.73 + if config.attachments then 3.74 + local file_upload_session = param.get("file_upload_session") or multirand.string( 3.75 + 32, 3.76 + '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 3.77 + ) 3.78 + file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "") 3.79 + ui.field.hidden{ name = "file_upload_session", value = file_upload_session } 3.80 + local files = File:new_selector() 3.81 + :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id") 3.82 + :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id } 3.83 + :reset_fields() 3.84 + :add_field("file.id") 3.85 + :add_field("draft_attachment.title") 3.86 + :add_field("draft_attachment.description") 3.87 + :add_order_by("draft_attachment.id") 3.88 + :exec() 3.89 + 3.90 + if #files > 0 then 3.91 + ui.container { 3.92 + content = function() 3.93 + for i, file in ipairs(files) do 3.94 + ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } } 3.95 + ui.container{ content = file.title or "" } 3.96 + ui.container{ content = file.description or "" } 3.97 + ui.field.boolean{ label = _"delete", name = "file_delete_" .. file.id, value = param.get("file_delete_" .. file.id) and true or false } 3.98 + slot.put("<br /><br />") 3.99 + end 3.100 + end 3.101 + } 3.102 + end 3.103 + 3.104 + local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json") 3.105 + local fh = io.open(filename, "r") 3.106 + if fh then 3.107 + local file_uploads = json.import(fh:read("*a")) 3.108 + for i, file_upload in ipairs(file_uploads) do 3.109 + ui.image{ module = "draft", view = "show_file_upload", params = { 3.110 + file_upload_session = file_upload_session, file_id = file_upload.id, preview = true 3.111 + } } 3.112 + ui.container{ content = file_upload.title or "" } 3.113 + ui.container{ content = file_upload.description or "" } 3.114 + ui.field.boolean{ label = _"delete", name = "file_upload_delete_" .. file_upload.id } 3.115 + slot.put("<br />") 3.116 + end 3.117 + end 3.118 + ui.container{ attr = { id = "file_upload_template", style = "display: none;" }, content = function() 3.119 + ui.field.text{ label = _"Title", name = "__ID_title__" } 3.120 + ui.field.text{ label = _"Description", name = "__ID_description__" } 3.121 + ui.field.image{ field_name = "__ID_file__" } 3.122 + end } 3.123 + ui.container{ attr = { id = "file_upload" }, content = function() 3.124 + end } 3.125 + ui.field.hidden{ attr = { id = "file_upload_last_id" }, name = "file_upload_last_id" } 3.126 + ui.script{ script = [[ var file_upload_id = 1; ]] } 3.127 + ui.tag{ tag = "a", content = _"Attach image", attr = { 3.128 + href = "#", 3.129 + onclick = "var html = document.getElementById('file_upload_template').innerHTML; html = html.replace('__ID_file__', 'file_' + file_upload_id); html = html.replace('__ID_title__', 'title_' + file_upload_id); html = html.replace('__ID_description__', 'description_' + file_upload_id); var el = document.createElement('div'); el.innerHTML = html; document.getElementById('file_upload').appendChild(el); document.getElementById('file_upload_last_id').value = file_upload_id; file_upload_id++; return false;" 3.130 + } } 3.131 + slot.put("<br />") 3.132 + 3.133 + slot.put("<br />") 3.134 + 3.135 + end 3.136 3.137 ui.tag{ 3.138 tag = "input",
4.1 --- a/app/main/draft/show.lua Mon Dec 09 15:54:57 2019 +0100 4.2 +++ b/app/main/draft/show.lua Mon Feb 10 21:10:49 2020 +0100 4.3 @@ -6,61 +6,122 @@ 4.4 return 4.5 end 4.6 4.7 +local member = app.session.member 4.8 + 4.9 +if member then 4.10 + draft.initiative:load_everything_for_member_id(member.id) 4.11 + draft.initiative.issue:load_everything_for_member_id(member.id) 4.12 +end 4.13 4.14 local source = param.get("source", atom.boolean) 4.15 4.16 -execute.view{ 4.17 - module = "issue", 4.18 - view = "_head", 4.19 - params = { issue = draft.initiative.issue } 4.20 -} 4.21 +execute.view{ module = "issue", view = "_head", params = { issue = draft.initiative.issue, link_issue = true } } 4.22 + 4.23 +ui.grid{ content = function() 4.24 4.25 -ui.section( function() 4.26 - 4.27 - ui.sectionHead( function() 4.28 - ui.link{ 4.29 - module = "initiative", view = "show", id = draft.initiative.id, 4.30 - content = function () 4.31 + ui.cell_main{ content = function() 4.32 + 4.33 + ui.container{ attr = { class = "mdl-card mdl-card__fullwidth mdl-shadow--2dp" }, content = function() 4.34 + 4.35 + ui.container{ attr = { class = "mdl-card__title mdl-card--has-fab mdl-card--border" }, content = function () 4.36 + 4.37 ui.heading { 4.38 - level = 1, 4.39 - content = draft.initiative.display_name 4.40 + attr = { class = "mdl-card__title-text" }, 4.41 + level = 2, 4.42 + content = function() 4.43 + ui.link{ 4.44 + module = "initiative", view = "show", id = draft.initiative.id, 4.45 + content = draft.initiative.display_name 4.46 + } 4.47 + ui.container{ content = _("Draft revision #{id}", { id = draft.id } ) } 4.48 + end 4.49 } 4.50 - end 4.51 - } 4.52 - ui.container { attr = { class = "right" }, content = function() 4.53 - if source then 4.54 - ui.link{ 4.55 - content = _"Rendered", 4.56 + end } 4.57 + 4.58 + ui.container{ attr = { class = "draft mdl-card__title mdl-card--border" }, content = function() 4.59 + if config.render_external_reference and config.render_external_reference.draft then 4.60 + config.render_external_reference.draft(draft, function (callback) 4.61 + ui.sectionRow(callback) 4.62 + end) 4.63 + end 4.64 + 4.65 + execute.view{ 4.66 module = "draft", 4.67 - view = "show", 4.68 - id = param.get_id(), 4.69 - params = { source = false } 4.70 + view = "_show", 4.71 + params = { draft = draft, source = source } 4.72 } 4.73 - else 4.74 - ui.link{ 4.75 - content = _"Source", 4.76 - module = "draft", 4.77 - view = "show", 4.78 - id = param.get_id(), 4.79 - params = { source = true } 4.80 - } 4.81 + 4.82 + 4.83 + 4.84 + end } 4.85 + 4.86 + if config.attachments then 4.87 + 4.88 + local files = File:new_selector() 4.89 + :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id") 4.90 + :add_where{ "draft_attachment.draft_id = ?", draft.id } 4.91 + :reset_fields() 4.92 + :add_field("file.id") 4.93 + :add_field("draft_attachment.title") 4.94 + :add_field("draft_attachment.description") 4.95 + :add_order_by("draft_attachment.id") 4.96 + :exec() 4.97 + 4.98 + if #files > 0 then 4.99 + ui.container { 4.100 + attr = { class = "mdl-card__content mdl-card--border" }, 4.101 + content = function() 4.102 + for i, file in ipairs(files) do 4.103 + ui.link{ module = "file", view = "show.jpg", id = file.id, content = function() 4.104 + ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } } 4.105 + end } 4.106 + ui.container{ content = file.title or "" } 4.107 + ui.container{ content = file.description or "" } 4.108 + slot.put("<br /><br />") 4.109 + end 4.110 + end 4.111 + } 4.112 + end 4.113 end 4.114 + 4.115 + ui.container{ attr = { class = "mdl-card__actions" }, content = function() 4.116 + if source then 4.117 + ui.link{ 4.118 + attr = { class = "mdl-button mdl-js-button" }, 4.119 + content = _"Rendered", 4.120 + module = "draft", 4.121 + view = "show", 4.122 + id = param.get_id(), 4.123 + params = { source = false } 4.124 + } 4.125 + else 4.126 + ui.link{ 4.127 + attr = { class = "mdl-button mdl-js-button" }, 4.128 + content = _"Source", 4.129 + module = "draft", 4.130 + view = "show", 4.131 + id = param.get_id(), 4.132 + params = { source = true } 4.133 + } 4.134 + end 4.135 + 4.136 + end } 4.137 end } 4.138 - ui.heading { level = 2, content = _("Draft revision #{id}", { id = draft.id } ) } 4.139 - end) 4.140 - 4.141 - if config.render_external_reference and config.render_external_reference.draft then 4.142 - config.render_external_reference.draft(draft, function (callback) 4.143 - ui.sectionRow(callback) 4.144 - end) 4.145 - end 4.146 - 4.147 - ui.sectionRow( function() 4.148 - 4.149 - execute.view{ 4.150 - module = "draft", 4.151 - view = "_show", 4.152 - params = { draft = draft, source = source } 4.153 + 4.154 + end } 4.155 + 4.156 + ui.cell_sidebar{ content = function() 4.157 + if config.logo then 4.158 + config.logo() 4.159 + end 4.160 + execute.view { 4.161 + module = "issue", view = "_sidebar", 4.162 + params = { 4.163 + issue = draft.initiative.issue, 4.164 + initiative = draft.initiative, 4.165 + member = app.session.member 4.166 + } 4.167 } 4.168 - end) 4.169 -end) 4.170 + end } 4.171 + 4.172 +end }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/app/main/draft/show_file_upload.lua Mon Feb 10 21:10:49 2020 +0100 5.3 @@ -0,0 +1,22 @@ 5.4 +local file_upload_session = param.get("file_upload_session") 5.5 +file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "") 5.6 + 5.7 +local file_id = param.get("file_id") 5.8 +file_id = string.gsub(file_id, "[^A-Za-z0-9]", "") 5.9 + 5.10 +local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. file_id .. ".jpg") 5.11 + 5.12 +if param.get("preview", atom.boolean) then 5.13 + filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. file_id .. ".preview.jpg") 5.14 +end 5.15 + 5.16 +local data 5.17 + 5.18 +local fh = io.open(filename, "r") 5.19 +if fh then 5.20 + data = fh:read("*a") 5.21 +end 5.22 + 5.23 + 5.24 +slot.set_layout(nil, content_type) 5.25 +slot.put_into("data", data)
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/app/main/file/show.jpg.lua Mon Feb 10 21:10:49 2020 +0100 6.3 @@ -0,0 +1,12 @@ 6.4 +local id = param.get_id() 6.5 + 6.6 +local file = File:by_id(id) 6.7 + 6.8 +local output = file.data 6.9 + 6.10 +if param.get("preview", atom.boolean) then 6.11 + output = file.preview_data 6.12 +end 6.13 + 6.14 +slot.set_layout(nil, file.content_type) 6.15 +slot.put_into("data", output)
7.1 --- a/app/main/initiative/show.lua Mon Dec 09 15:54:57 2019 +0100 7.2 +++ b/app/main/initiative/show.lua Mon Feb 10 21:10:49 2020 +0100 7.3 @@ -135,6 +135,35 @@ 7.4 end 7.5 } 7.6 7.7 + if config.attachments then 7.8 + 7.9 + local files = File:new_selector() 7.10 + :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id") 7.11 + :add_where{ "draft_attachment.draft_id = ?", initiative.current_draft.id } 7.12 + :reset_fields() 7.13 + :add_field("file.id") 7.14 + :add_field("draft_attachment.title") 7.15 + :add_field("draft_attachment.description") 7.16 + :add_order_by("draft_attachment.id") 7.17 + :exec() 7.18 + 7.19 + if #files > 0 then 7.20 + ui.container { 7.21 + attr = { class = "mdl-card__content mdl-card--border" }, 7.22 + content = function() 7.23 + for i, file in ipairs(files) do 7.24 + ui.link{ module = "file", view = "show.jpg", id = file.id, content = function() 7.25 + ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } } 7.26 + end } 7.27 + ui.container{ content = file.title or "" } 7.28 + ui.container{ content = file.description or "" } 7.29 + slot.put("<br /><br />") 7.30 + end 7.31 + end 7.32 + } 7.33 + end 7.34 + end 7.35 + 7.36 local drafts_count = initiative:get_reference_selector("drafts"):count() 7.37 7.38 if not config.voting_only then
8.1 --- a/model/draft.lua Mon Dec 09 15:54:57 2019 +0100 8.2 +++ b/model/draft.lua Mon Feb 10 21:10:49 2020 +0100 8.3 @@ -97,5 +97,19 @@ 8.4 8.5 draft:render_content() 8.6 8.7 + local draft_attachments = DraftAttachment:new_selector() 8.8 + :add_where{ "draft_id = ?", old_draft.id } 8.9 + :exec() 8.10 + 8.11 + for i, draft_attachment in ipairs(draft_attachments) do 8.12 + local new_draft_attachment = DraftAttachment:new() 8.13 + new_draft_attachment.draft_id = draft.id 8.14 + new_draft_attachment.file_id = draft_attachment.file_id 8.15 + new_draft_attachment.title = draft_attachment.title 8.16 + new_draft_attachment.description = draft_attachment.description 8.17 + new_draft_attachment:save() 8.18 + end 8.19 + 8.20 slot.put_into("notice", _"The initiative text has been updated") 8.21 + return draft.id 8.22 end
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/model/draft_attachment.lua Mon Feb 10 21:10:49 2020 +0100 9.3 @@ -0,0 +1,5 @@ 9.4 +DraftAttachment = mondelefant.new_class() 9.5 +DraftAttachment.table = "draft_attachment" 9.6 +DraftAttachment.primary_key = "id" 9.7 + 9.8 +
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/model/file.lua Mon Feb 10 21:10:49 2020 +0100 10.3 @@ -0,0 +1,8 @@ 10.4 +File = mondelefant.new_class() 10.5 +File.table = "file" 10.6 +File.primary_key = "id" 10.7 + 10.8 +File.binary_columns = { 10.9 + data = true, 10.10 + preview_data = true 10.11 +}