radiant-database_mailer-extension 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/README.md +159 -0
  2. data/Rakefile +120 -0
  3. data/app/controllers/admin/form_datas_controller.rb +77 -0
  4. data/app/controllers/database_mailer_processing.rb +19 -0
  5. data/app/helpers/admin/form_datas_helper.rb +57 -0
  6. data/app/models/form_data.rb +93 -0
  7. data/app/models/form_data_asset.rb +14 -0
  8. data/app/views/admin/form_datas/_export.html.haml +33 -0
  9. data/app/views/admin/form_datas/_filters.html.haml +27 -0
  10. data/app/views/admin/form_datas/index.html.haml +34 -0
  11. data/app/views/admin/form_datas/show.html.haml +49 -0
  12. data/config/routes.rb +7 -0
  13. data/database_mailer_extension.rb +31 -0
  14. data/db/migrate/001_create_form_datas.rb +16 -0
  15. data/db/migrate/002_add_data_columns.rb +13 -0
  16. data/db/migrate/20090722135916_create_form_data_assets.rb +21 -0
  17. data/features/datasets/database_mailer_dataset.rb +19 -0
  18. data/features/datasets/mailers_dataset.rb +69 -0
  19. data/features/fixtures/attachment.jpg +0 -0
  20. data/features/saving_emails_to_database.feature +45 -0
  21. data/features/step_definitions/admin_steps.rb +6 -0
  22. data/features/step_definitions/email_steps.rb +73 -0
  23. data/features/step_definitions/form_data_steps.rb +3 -0
  24. data/features/step_definitions/webrat_steps.rb +119 -0
  25. data/features/support/env.rb +28 -0
  26. data/features/support/paths.rb +25 -0
  27. data/lib/radiant-database_mailer-extension.rb +8 -0
  28. data/lib/tasks/database_mailer_extension_tasks.rake +31 -0
  29. data/public/javascripts/admin/database_mailer.js +73 -0
  30. data/public/stylesheets/sass/admin/database_mailer.sass +235 -0
  31. data/radiant-database_mailer-extension.gemspec +26 -0
  32. data/spec/controllers/form_datas_controller_spec.rb +272 -0
  33. data/spec/controllers/mail_controller_spec.rb +40 -0
  34. data/spec/helpers/form_datas_helper_spec.rb +5 -0
  35. data/spec/models/form_data_asset_spec.rb +11 -0
  36. data/spec/models/form_data_spec.rb +151 -0
  37. data/spec/spec.opts +6 -0
  38. data/spec/spec_helper.rb +37 -0
  39. data/spec/views/index.html.erb_spec.rb +25 -0
  40. metadata +139 -0
data/README.md ADDED
@@ -0,0 +1,159 @@
1
+ Database Mailer
2
+ ===
3
+
4
+ About
5
+ ---
6
+
7
+ A [Radiant][rd] Extension by [Aissac][ai] that adds database persistence to emailed forms. It works on top of the Radiant [Mailer Extension][rme] and the fields recorded to the database are user defined. The extension adds a tab to the Radiant admin interface allowing you to browse saved records.
8
+
9
+ Tested on Radiant 0.7.1, 0.8 and 0.9 RC1.
10
+
11
+ Check out the [screencast][rce]
12
+
13
+ Features
14
+ ---
15
+
16
+ * Save posted form fields and entire mail message to the database
17
+ * Save e-mail attachments using paperclip
18
+ * Configurable save-to-database for mailer forms
19
+ * Add fields to be saved without loosing data
20
+ * Admin interface to browse saved records
21
+ * Export data to CSV and XLS
22
+
23
+ Important Notice!
24
+ ---
25
+
26
+ The git branches on this repository hold stable versions of the extension for older versions of Radiant CMS. For example the _0.8_ branch is compatible with Radiant 0.8.
27
+
28
+ To checkout one of these branches:
29
+
30
+ git clone git://github.com/Aissac/radiant-database-mailer-extension.git vendor/extensions/database_mailer
31
+ cd vendor/extensions/database_mailer
32
+ git checkout -b <branch-name> origin/<remote-branch-name>
33
+
34
+ As an example if you're working on Radiant 0.8 you will need to checkout the 0.8 branch:
35
+
36
+ cd vendor/extensions/database_mailer
37
+ git checkout -b my_branch origin/0.8
38
+
39
+ Installation
40
+ ---
41
+
42
+ Radiant Database Mailer Extension has three dependecies, the Radiant Mailer Extension, the `will_paginate` gem/plugin and the `paperclip` gem/plugin
43
+
44
+ Install the `mailer` extension:
45
+
46
+ git clone git://github.com/radiant/radiant-mailer-extension.git vendor/extensions/mailer
47
+
48
+ ###Note
49
+
50
+ At the time being you will need Aissac's version of the [Radiant Mailer Extension][arme], as it incorporates sending e-mails with attachments.
51
+
52
+ the `will_paginate` gem/plugin:
53
+
54
+ git clone git://github.com/mislav/will_paginate.git vendor/plugins/will_paginate
55
+
56
+ or
57
+
58
+ sudo gem install will_paginate
59
+
60
+ and the `paperclip` gem/plugin
61
+
62
+ git clone git://github.com/thoughtbot/paperclip.git vendor/plugins/paperclip
63
+
64
+ or
65
+
66
+ sudo gem install paperclip
67
+
68
+ Next edit `config/environment.rb` and add desired fields to be recorded:
69
+
70
+ DATABASE_MAILER_COLUMNS = {
71
+ :name => :string,
72
+ :message => :text,
73
+ :email => :string
74
+ }
75
+
76
+ And finally add the [Database Mailer Extension][rdme]:
77
+
78
+ git clone git://github.com/Aissac/radiant-database-mailer-extension.git vendor/extensions/database_mailer
79
+
80
+ Migrate and update the extension:
81
+
82
+ rake radiant:extensions:database_mailer:migrate
83
+ rake radiant:extensions:database_mailer:update
84
+
85
+ Configuration
86
+ ---
87
+
88
+ Adding fields to the `DATABASE_MAILER_COLUMNS` hash and re-running `rake radiant:extensions:database_mailer:migrate` nondestructively adds fields to be saved. Fields removed from the hash are not deleted.
89
+
90
+ Look at the Mailer Extension README for information on how to configure mail delivery.
91
+
92
+ If you set `save_to_database` to false in the Mailer config, saving to the database is skipped and just mail delivery takes place. Example (in the `mailer` page part):
93
+
94
+ subject: From the website of Whatever
95
+ from: noreply@example.com
96
+ redirect_to: /contact/thank-you
97
+ save_to_database: false
98
+ recipients:
99
+ - one@one.com
100
+ - two@two.com
101
+
102
+ Any attachments that the e-mail might have will be saved on the file system. They can be downloaded from the details page of every record.
103
+
104
+ If you want to take advantage of the blob field you need to create a `email` page part. The blob field keeps the sent version of the email.
105
+
106
+ Fields that are not specified by `DATABASE_MAILER_COLUMNS` are silently ignored.
107
+
108
+ Usage
109
+ ---
110
+
111
+ Create your Mailer pages and make sure to use the same field names:
112
+
113
+ <r:mailer:form>
114
+ <label for="name">Name:</label><br/>
115
+ <r:mailer:text name="name" /><br/>
116
+
117
+ <label for="email">Email:</label><br/>
118
+ <r:mailer:text name="email" /><br/>
119
+
120
+ <label for="message">Message:</label><br/>
121
+ <r:mailer:textarea name="message" /> <br/>
122
+
123
+ <label for="attachment">Image:</label><br/>
124
+ <r:mailer:file name="attachment" /><br/>
125
+
126
+ <input type="submit" value="Send" />
127
+ </r:mailer:form>
128
+
129
+ Create the `mailer` page part:
130
+
131
+ subject: From the website of Whatever
132
+ from: noreply@example.com
133
+ redirect_to: /contact/thank-you
134
+ recipients:
135
+ - one@one.com
136
+ - two@two.com
137
+
138
+ Create an `email` page part (to take advantage of the blob field):
139
+
140
+ <r:mailer>
141
+ Name: <r:get name="name" />
142
+ Email: <r:get name="email" />
143
+ Message: <r:get name="message" />
144
+ </r:mailer>
145
+
146
+ Contributors
147
+ ---
148
+
149
+ * Cristi Duma ([@cristi_duma][cd])
150
+ * Istvan Hoka ([@ihoka][ih])
151
+
152
+ [rd]: http://radiantcms.org/
153
+ [ai]: http://www.aissac.ro/
154
+ [rme]: http://github.com/radiant/radiant-mailer-extension
155
+ [arme]: http://github.com/Aissac/radiant-mailer-extension
156
+ [rdme]: http://blog.aissac.ro/radiant/database-mailer-extension/
157
+ [cd]: http://twitter.com/cristi_duma
158
+ [ih]: http://twitter.com/ihoka
159
+ [rce]:http://blog.aissac.ro/2010/03/16/episode-5-radiant-database-mailer-extension/
data/Rakefile ADDED
@@ -0,0 +1,120 @@
1
+ # I think this is the one that should be moved to the extension Rakefile template
2
+
3
+ # In rails 1.2, plugins aren't available in the path until they're loaded.
4
+ # Check to see if the rspec plugin is installed first and require
5
+ # it if it is. If not, use the gem version.
6
+
7
+ # Determine where the RSpec plugin is by loading the boot
8
+ unless defined? RADIANT_ROOT
9
+ ENV["RAILS_ENV"] = "test"
10
+ case
11
+ when ENV["RADIANT_ENV_FILE"]
12
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
13
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
14
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
15
+ else
16
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
17
+ end
18
+ end
19
+
20
+ require 'rake'
21
+ require 'rake/rdoctask'
22
+ require 'rake/testtask'
23
+
24
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
25
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
26
+ require 'spec/rake/spectask'
27
+ # require 'spec/translator'
28
+
29
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
30
+ Object.send(:remove_const, :RADIANT_ROOT)
31
+
32
+ extension_root = File.expand_path(File.dirname(__FILE__))
33
+
34
+ task :default => :spec
35
+ task :stats => "spec:statsetup"
36
+
37
+ desc "Run all specs in spec directory"
38
+ Spec::Rake::SpecTask.new(:spec) do |t|
39
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
40
+ t.spec_files = FileList['spec/**/*_spec.rb']
41
+ end
42
+
43
+ namespace :spec do
44
+ desc "Run all specs in spec directory with RCov"
45
+ Spec::Rake::SpecTask.new(:rcov) do |t|
46
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
47
+ t.spec_files = FileList['spec/**/*_spec.rb']
48
+ t.rcov = true
49
+ t.rcov_opts = ["--exclude", "spec/*,gems/*", "--rails"]
50
+ end
51
+
52
+ desc "Print Specdoc for all specs"
53
+ Spec::Rake::SpecTask.new(:doc) do |t|
54
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
55
+ t.spec_files = FileList['spec/**/*_spec.rb']
56
+ end
57
+
58
+ [:models, :controllers, :views, :helpers].each do |sub|
59
+ desc "Run the specs under spec/#{sub}"
60
+ Spec::Rake::SpecTask.new(sub) do |t|
61
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
62
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
63
+ end
64
+ end
65
+
66
+ # Hopefully no one has written their extensions in pre-0.9 style
67
+ # desc "Translate specs from pre-0.9 to 0.9 style"
68
+ # task :translate do
69
+ # translator = ::Spec::Translator.new
70
+ # dir = RAILS_ROOT + '/spec'
71
+ # translator.translate(dir, dir)
72
+ # end
73
+
74
+ # Setup specs for stats
75
+ task :statsetup do
76
+ require 'code_statistics'
77
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
78
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
79
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
80
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
81
+ ::CodeStatistics::TEST_TYPES << "Model specs"
82
+ ::CodeStatistics::TEST_TYPES << "View specs"
83
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
84
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
85
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
86
+ end
87
+
88
+ namespace :db do
89
+ namespace :fixtures do
90
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
91
+ task :load => :environment do
92
+ require 'active_record/fixtures'
93
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
94
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
95
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ desc 'Generate documentation for the database_mailer extension.'
103
+ Rake::RDocTask.new(:rdoc) do |rdoc|
104
+ rdoc.rdoc_dir = 'rdoc'
105
+ rdoc.title = 'DatabaseMailerExtension'
106
+ rdoc.options << '--line-numbers' << '--inline-source'
107
+ rdoc.rdoc_files.include('README')
108
+ rdoc.rdoc_files.include('lib/**/*.rb')
109
+ end
110
+
111
+ # For extensions that are in transition
112
+ desc 'Test the database_mailer extension.'
113
+ Rake::TestTask.new(:test) do |t|
114
+ t.libs << 'lib'
115
+ t.pattern = 'test/**/*_test.rb'
116
+ t.verbose = true
117
+ end
118
+
119
+ # Load any custom rakefiles for extension
120
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
@@ -0,0 +1,77 @@
1
+ class Admin::FormDatasController < ApplicationController
2
+
3
+ require 'fastercsv'
4
+ before_filter :attach_assets
5
+ LIST_PARAMS_BASE = [:page, :sort_by, :sort_order]
6
+ EXPORT_COLUMNS = FormData::SORT_COLUMNS.sort - ["exported"] + ["blob"]
7
+ def index
8
+
9
+ @urls = FormData.find_all_group_by_url
10
+ filter_by_params(FormData::FILTER_COLUMNS)
11
+ respond_to do |format|
12
+ format.html {
13
+ @saved_items = FormData.form_paginate(list_params)
14
+ }
15
+
16
+ exported_at = Time.now
17
+ selected_export_columns = EXPORT_COLUMNS.reject{|k| params["export_#{k}"].blank?}
18
+
19
+ format.csv {
20
+ csv_string = FormData.export_csv(list_params, selected_export_columns, exported_at, !params[:include_all].blank?)
21
+ send_data csv_string,
22
+ :type => "text/csv",
23
+ :filename => "export_#{exported_at.strftime("%Y-%m-%d_%H-%M")}.csv",
24
+ :disposition => 'attachment'
25
+ }
26
+ format.xls {
27
+ xls_path = FormData.export_xls(list_params, selected_export_columns, exported_at, !params[:include_all].blank?)
28
+ send_file xls_path,
29
+ :type => "application/vnd.ms-excel",
30
+ :filename => "form_data_#{exported_at.strftime("%Y-%m-%d_%H-%M")}.xls",
31
+ :disposition => 'attachment'
32
+ }
33
+ end
34
+ end
35
+
36
+ def show
37
+ @form_data = FormData.find(params[:id])
38
+ end
39
+
40
+ def destroy
41
+ @form_data = FormData.find(params[:id])
42
+ @form_data.destroy
43
+ flash[:notice] = "Record deleted!"
44
+ redirect_to admin_form_datas_path
45
+ end
46
+
47
+ def list_params
48
+ @list_params ||= {}
49
+ end
50
+ helper_method :list_params
51
+
52
+ protected
53
+ def filter_by_params(args)
54
+ args = args + LIST_PARAMS_BASE
55
+ args.each do |arg|
56
+ list_params[arg] = params[:reset] ? params[arg] : params[arg] || cookies[arg]
57
+ end
58
+ list_params[:page] ||= "1"
59
+
60
+ update_list_params_cookies(args)
61
+
62
+ # pentru will_paginate
63
+ params[:page] = list_params[:page]
64
+ end
65
+
66
+ def update_list_params_cookies(args)
67
+ args.each do |key|
68
+ cookies[key] = { :value => list_params[key], :path => "/#{controller_path}" }
69
+ end
70
+ end
71
+
72
+ def attach_assets
73
+ include_stylesheet "admin/database_mailer"
74
+ include_javascript "admin/database_mailer"
75
+ end
76
+
77
+ end
@@ -0,0 +1,19 @@
1
+ module DatabaseMailerProcessing
2
+
3
+ def process_mail_with_database(mail, config)
4
+ if mail.valid?
5
+ page = mail.page
6
+ plain_body = (page.part( :email ) ? page.render_part( :email ) : page.render_part( :email_plain ))
7
+
8
+ if config[:save_to_database] || config[:save_to_database].nil?
9
+ fd = FormData.create(mail.data.merge(:url => mail.page.url, :blob => plain_body))
10
+ mail.data.each do |k, v|
11
+ if v.class.to_s == "Tempfile"
12
+ FormDataAsset.create(:form_data_id => fd.id, :field_name => k, :attachment => v)
13
+ end
14
+ end
15
+ end
16
+ process_mail_without_database(mail, config)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,57 @@
1
+ module Admin::FormDatasHelper
2
+ SORT_CYCLE = {'asc' => 'desc', 'desc' => 'none', 'none' => 'asc'}
3
+
4
+ def sortable_column_head(label, attribute)
5
+ current_order = (currently_sorting_by?(attribute) && %w(none asc desc).include?(list_params[:sort_order])) ? list_params[:sort_order] : 'none'
6
+ dom_class = currently_sorting_by?(attribute) ? "sort_#{current_order}" : nil
7
+
8
+ link_to(label,
9
+ params.merge(list_params).merge(:sort_by => attribute, :sort_order => SORT_CYCLE[current_order], :reset => 1),
10
+ :class => dom_class)
11
+ end
12
+
13
+ def filter_actions_tag
14
+ submit_tag("Filter") + content_tag('span', ' | ' + reset_filters_tag)
15
+ end
16
+
17
+ def reset_filters_tag
18
+ link_to("Reset", :reset => 1)
19
+ end
20
+
21
+ def each_data_column(&block)
22
+ DATABASE_MAILER_COLUMNS.each_key do |key|
23
+ yield key
24
+ end
25
+ end
26
+
27
+ def data_columns
28
+ DATABASE_MAILER_COLUMNS.keys
29
+ end
30
+
31
+ def date_format(timestamp)
32
+ timestamp && l(timestamp, :format => :long)
33
+ end
34
+
35
+ def filters_present(&block)
36
+ if (DATABASE_MAILER_COLUMNS.keys + [:url]).any? { |k| !list_params[k].blank?}
37
+ yield
38
+ end
39
+ end
40
+
41
+ def current_filters
42
+ all_filters = DATABASE_MAILER_COLUMNS.keys + [:url]
43
+ all_filters.map do |k|
44
+ k unless list_params[k].blank?
45
+ end.compact.join(", ")
46
+ end
47
+
48
+ def export_columns
49
+ Admin::FormDatasController::EXPORT_COLUMNS
50
+ end
51
+
52
+ protected
53
+
54
+ def currently_sorting_by?(attribute)
55
+ list_params[:sort_by] == attribute.to_s
56
+ end
57
+ end
@@ -0,0 +1,93 @@
1
+ require 'fastercsv'
2
+ require 'spreadsheet'
3
+
4
+ class FormData < ActiveRecord::Base
5
+
6
+ has_many :form_data_assets, :dependent => :destroy
7
+
8
+ SORT_COLUMNS = DATABASE_MAILER_COLUMNS.keys.map(&:to_s) + ['created_at', 'url', 'exported']
9
+ FILTER_COLUMNS = DATABASE_MAILER_COLUMNS.keys + [:url]
10
+
11
+ DATABASE_MAILER_COLUMNS.each_key do | col |
12
+ FormData.named_scope :"by_#{col}", lambda { |item|
13
+ {:conditions => ["LOWER(#{col}) LIKE ?", "%#{item.to_s.downcase}%"]}
14
+ }
15
+ end
16
+ named_scope :by_url, lambda{ |item| {:conditions => ["url = ?", item]}}
17
+ named_scope :not_exported, :conditions => {:exported => nil}
18
+
19
+ def self.form_paginate(params)
20
+ options = {
21
+ :page => params[:page],
22
+ :per_page => 10,
23
+ }
24
+ if SORT_COLUMNS.include?(params[:sort_by]) && %w(asc desc).include?(params[:sort_order])
25
+ options[:order] = "#{params[:sort_by]} #{params[:sort_order]}"
26
+ end
27
+ params.reject { |k, v| !FILTER_COLUMNS.include?(k) }.
28
+ inject(FormData) { |scope, pair| pair[1].blank? ? scope : scope.send(:"by_#{pair[0]}", pair[1]) }.
29
+ paginate(options)
30
+ end
31
+
32
+ def self.find_all_group_by_url
33
+ find(:all, :group => 'url', :select => 'url')
34
+ end
35
+
36
+ def self.find_for_export(params, export_all)
37
+ options = {}
38
+ if SORT_COLUMNS.include?(params[:sort_by]) && %w(asc desc).include?(params[:sort_order])
39
+ options[:order] = "#{params[:sort_by]} #{params[:sort_order]}"
40
+ end
41
+
42
+ initial = export_all ? FormData : FormData.not_exported
43
+
44
+ params.reject { |k, v| !FILTER_COLUMNS.include?(k) }.
45
+ inject(initial) { |scope, pair| pair[1].blank? ? scope : scope.send(:"by_#{pair[0]}", pair[1]) }.find(:all, :order => options[:order])
46
+ end
47
+
48
+ def self.export_csv(params, selected_export_columns, exported_at, export_all=false)
49
+ @items = find_for_export(params, export_all)
50
+
51
+ FasterCSV.generate do |csv|
52
+ csv << selected_export_columns.map{|k| k.capitalize}
53
+ @items.each do |ei|
54
+ csv << selected_export_columns.map do |k|
55
+ formatting_for_csv(ei.send(k))
56
+ end
57
+ ei.exported = exported_at.to_s(:db)
58
+ ei.save
59
+ end
60
+ end
61
+ end
62
+
63
+ def self.export_xls(params, selected_export_columns, exported_at, export_all=false)
64
+ items = find_for_export(params, export_all)
65
+ book = Spreadsheet::Workbook.new
66
+ sheet = book.create_worksheet :name => 'Form Data'
67
+
68
+ sheet.row(0).replace(selected_export_columns.map{|k| k.capitalize})
69
+
70
+ items.each_with_index do |item, i|
71
+ sheet.row(i+1).replace(selected_export_columns.map {|k| item.send(k)})
72
+ item.exported = exported_at.to_s(:db)
73
+ item.save
74
+ end
75
+
76
+ tmp_file = Tempfile.new("form_data")
77
+ book.write tmp_file
78
+ tmp_file.path
79
+ end
80
+
81
+ def self.formatting_for_csv(item)
82
+ if Time === item
83
+ item.to_s(:db)
84
+ else
85
+ item.to_s.gsub(/\s/, ' ')
86
+ end
87
+ end
88
+
89
+ def initialize(params={})
90
+ data = params.dup.delete_if { |k, v| !self.class.column_names.include?(k.to_s) }
91
+ super(data)
92
+ end
93
+ end
@@ -0,0 +1,14 @@
1
+ require 'paperclip'
2
+
3
+ class FormDataAsset < ActiveRecord::Base
4
+ belongs_to :form_data
5
+
6
+ has_attached_file :attachment, :styles => { :thumb => '100x100>' }
7
+
8
+ IMAGE_CONTENT_TYPES = ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg']
9
+
10
+ def image?
11
+ IMAGE_CONTENT_TYPES.include? attachment_content_type
12
+ end
13
+
14
+ end
@@ -0,0 +1,33 @@
1
+ #x_filters
2
+ %a#x_expander.expand{:href => "javascript:;"} Export
3
+ #x_form{:style => "display:none"}
4
+ - form_tag(admin_form_datas_path, {:method => :get}) do
5
+ = list_params.map {|k,v| hidden_field_tag(k,v)}.join
6
+ %table.export
7
+ %tr
8
+ %td{:colspan => "2"} Choose the columns you want to export:
9
+ - export_columns.each do |ec|
10
+ %tr
11
+ %th= check_box_tag "export_#{ec}", ec, true
12
+ %td
13
+ %label{:for => "export_#{ec}"}
14
+ = ec.to_s.capitalize
15
+ %tr
16
+ %th= check_box_tag "include_all", "yes"
17
+ %td
18
+ %label{:for => "include_all"} Include allready exported
19
+ %tr
20
+ %td.sep{:colspan => "2"} Choose the format:
21
+ %tr
22
+ %th= radio_button_tag "format", "csv"
23
+ %td
24
+ %label{:for => "format_csv"} Comma separated values (CSV)
25
+ %tr
26
+ %th= radio_button_tag "format", "xls"
27
+ %td
28
+ %label{:for => "format_xls"} Microsoft Excel Sheet (XLS)
29
+ %tr
30
+ %th &nbsp;
31
+ %td
32
+ = submit_tag "Export"
33
+ %a.close{:href => "javascript:closeX()"} Close
@@ -0,0 +1,27 @@
1
+ #filters
2
+ %a#expander.expand{:href => 'javascript:;'} Filter
3
+ #current_filters
4
+ - filters_present do
5
+ Applied filters:
6
+ = current_filters
7
+ = link_to 'Reset', :reset => 1
8
+ #form{:style => "display:none"}
9
+ - form_tag({}, {:method => :get}) do
10
+ = hidden_field_tag(:reset => 1)
11
+ %table.search
12
+ %tr
13
+ %th
14
+ %label{:for => "url"} URL:
15
+ %td
16
+ = select_tag("url", '<option value="">- All -</option>' + options_from_collection_for_select(@urls, "url", "url", list_params[:url]))
17
+ - each_data_column do |k|
18
+ %tr
19
+ %th
20
+ %label{:for => k}
21
+ = k.to_s.capitalize + ":"
22
+ %td
23
+ = text_field_tag k, list_params[k]
24
+ %tr
25
+ %th &nbsp;
26
+ %td= filter_actions_tag
27
+ %a.close{:href => "javascript:close()"} Close
@@ -0,0 +1,34 @@
1
+ .grey
2
+ #filtering
3
+ = render :partial => "filters"
4
+ = render :partial => "export"
5
+ #results
6
+ %table.results
7
+ %thead
8
+ %tr
9
+ %th.created_at= sortable_column_head "Created at", :created_at
10
+ %th.url= sortable_column_head "URL", :url
11
+ - each_data_column do |k|
12
+ %th= sortable_column_head k.to_s.capitalize, k
13
+ %th.exported= sortable_column_head "Exported", :exported
14
+ %th.actions Actions
15
+ %tbody
16
+ - @saved_items.each do |si|
17
+ %tr
18
+ %td= date_format(si.created_at)
19
+ %td= si.url
20
+ = data_columns.map { |k| "<td>#{si.send(k)}</td>" }
21
+ %td= si.exported ? date_format(si.exported) : "no"
22
+ %td.actions
23
+ = link_to "Show", admin_form_data_path(si)
24
+ = link_to 'Delete', admin_form_data_path(si.id), :method => :delete, :confirm => "Really delete record?"
25
+ - if @saved_items.empty?
26
+ %tr
27
+ %td{:colspan => data_columns.size + 2} No Results!
28
+ %tfoot
29
+ %tr
30
+ %th{:colspan => 4}
31
+ = page_entries_info @saved_items
32
+ %th{:colspan => "#{data_columns.size}"}
33
+ = will_paginate @saved_items, :inner_window => 1, :outer_window => 1
34
+
@@ -0,0 +1,49 @@
1
+
2
+ %h1 Form Data
3
+
4
+ #show.clearfix
5
+ #tab_control
6
+ #tabs.tabs
7
+ %a#details_lnk.tab.here{ :href => "#", :onclick => "show_details();" }
8
+ %span details
9
+ - unless @form_data
10
+ %a#attachments_lnk.tab{ :href => "#", :onclick => "show_attachments();" }
11
+ %span attachments
12
+ #pages.pages
13
+ #details.page
14
+ %table.result
15
+ %tr
16
+ %th Created_at
17
+ %td= date_format(@form_data.created_at)
18
+ %th Sent version of the email
19
+ %tr
20
+ %th URL:
21
+ %td= @form_data.url
22
+ %td{ :rowspan => "#{data_columns.size + 2}" }= simple_format(@form_data.blob)
23
+ - data_columns.each do |dc|
24
+ %tr
25
+ %th= dc.to_s.capitalize
26
+ %td= @form_data.send(dc)
27
+ %tr
28
+ %th Exported
29
+ %td= @form_data.exported? ? date_format(@form_data.exported) : "no"
30
+ - unless @form_data
31
+ #attachments.page{ :style => "display:none;"}
32
+ %table.attachments
33
+ %thead
34
+ %tr
35
+ %th Field Name
36
+ %th Link
37
+ %th Thumbnail
38
+ %tbody
39
+ - @form_data.form_data_assets.each do |att|
40
+ %tr
41
+ %td= att.field_name.blank? ? "Field:" : att.field_name.capitalize
42
+ %td
43
+ = link_to att.attachment_file_name, att.attachment.url
44
+ - if att.image?
45
+ %td
46
+ = image_tag att.attachment.url(:thumb)
47
+ - else
48
+ %td &nbsp;
49
+ = link_to "Back", admin_form_datas_path, :class => "back"