infopark_rails_connector 6.8.0.beta.200.621.4c8e1b0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +59 -0
- data/app/assets/images/admin/minus.gif +0 -0
- data/app/assets/images/bg80.png +0 -0
- data/app/assets/images/edit.png +0 -0
- data/app/assets/images/icons/mm_generic.png +0 -0
- data/app/assets/images/icons/mm_menu.png +0 -0
- data/app/assets/images/ratings/star.gif +0 -0
- data/app/assets/images/time_machine/calendar-menuarrow.gif +0 -0
- data/app/assets/images/time_machine/calendar_bg.png +0 -0
- data/app/assets/images/time_machine/icon.png +0 -0
- data/app/assets/images/time_machine/slider_bg.png +0 -0
- data/app/assets/images/time_machine/slider_handle.png +0 -0
- data/app/assets/images/time_machine/timemachine_bg.png +0 -0
- data/app/assets/javascripts/comments.js +29 -0
- data/app/assets/javascripts/editmarker.js +240 -0
- data/app/assets/javascripts/infopark_rails_connector.js.erb +3 -0
- data/app/assets/javascripts/initializer.js +9 -0
- data/app/assets/javascripts/ratings.js +26 -0
- data/app/assets/javascripts/time_machine/calendar-setup.js +200 -0
- data/app/assets/javascripts/time_machine/calendar.js +1806 -0
- data/app/assets/javascripts/time_machine/lang/calendar-de.js +127 -0
- data/app/assets/javascripts/time_machine/lang/calendar-en.js +127 -0
- data/app/assets/javascripts/time_machine/lang/calendar-es.js +129 -0
- data/app/assets/javascripts/time_machine/lang/calendar-fr.js +125 -0
- data/app/assets/javascripts/time_machine/lang/calendar-it.js +124 -0
- data/app/assets/javascripts/time_machine/slider.js +278 -0
- data/app/assets/javascripts/time_machine.js +8 -0
- data/app/assets/stylesheets/editmarker.css +70 -0
- data/app/assets/stylesheets/infopark_rails_connector.css.erb +4 -0
- data/app/assets/stylesheets/ratings.css +97 -0
- data/app/assets/stylesheets/time_machine/time_machine.css +292 -0
- data/app/assets/stylesheets/time_machine.css +6 -0
- data/app/controllers/cms_controller.rb +6 -0
- data/app/controllers/comments_controller.rb +6 -0
- data/app/controllers/crm_form_controller.rb +2 -0
- data/app/controllers/pdf_controller.rb +6 -0
- data/app/controllers/rails_connector/default_cms_controller.rb +40 -0
- data/app/controllers/rails_connector/default_comments_controller.rb +71 -0
- data/app/controllers/rails_connector/default_crm_form_controller.rb +167 -0
- data/app/controllers/rails_connector/default_pdf_controller.rb +136 -0
- data/app/controllers/rails_connector/default_ratings_controller.rb +84 -0
- data/app/controllers/rails_connector/default_rss_controller.rb +29 -0
- data/app/controllers/rails_connector/default_search_controller.rb +60 -0
- data/app/controllers/rails_connector/default_user_controller.rb +267 -0
- data/app/controllers/rails_connector/pdf_external_controller.rb +54 -0
- data/app/controllers/rails_connector/time_machine_controller.rb +48 -0
- data/app/controllers/ratings_controller.rb +6 -0
- data/app/controllers/rss_controller.rb +6 -0
- data/app/controllers/search_controller.rb +2 -0
- data/app/controllers/seo_sitemap_controller.rb +12 -0
- data/app/controllers/user_controller.rb +2 -0
- data/app/helpers/cms_helper.rb +6 -0
- data/app/helpers/cms_routing_helper.rb +6 -0
- data/app/helpers/crm_form_helper.rb +3 -0
- data/app/helpers/rails_connector/cms_asset_helper.rb +51 -0
- data/app/helpers/rails_connector/default_cms_helper.rb +27 -0
- data/app/helpers/rails_connector/default_cms_routing_helper.rb +93 -0
- data/app/helpers/rails_connector/default_crm_form_helper.rb +58 -0
- data/app/helpers/rails_connector/default_ratings_helper.rb +38 -0
- data/app/helpers/rails_connector/default_user_helper.rb +90 -0
- data/app/helpers/rails_connector/display_helper.rb +117 -0
- data/app/helpers/rails_connector/error_messages_helper.rb +23 -0
- data/app/helpers/rails_connector/layout_helper.rb +30 -0
- data/app/helpers/rails_connector/link_helper.rb +88 -0
- data/app/helpers/rails_connector/mandatory_label_helper.rb +10 -0
- data/app/helpers/rails_connector/marker_helper.rb +363 -0
- data/app/helpers/rails_connector/menu_helper.rb +72 -0
- data/app/helpers/rails_connector/micronav_helper.rb +107 -0
- data/app/helpers/rails_connector/seo_helper.rb +44 -0
- data/app/helpers/rails_connector/table_of_contents_helper.rb +20 -0
- data/app/helpers/rails_connector/time_machine_helper.rb +24 -0
- data/app/helpers/rails_connector/tracking_helper.rb +32 -0
- data/app/helpers/ratings_helper.rb +4 -0
- data/app/helpers/user_helper.rb +3 -0
- data/app/mailers/confirmation_mailer.rb +13 -0
- data/app/models/crm_form.rb +2 -0
- data/app/models/named_link.rb +2 -0
- data/app/models/obj.rb +9 -0
- data/app/models/rails_connector/default_comment.rb +28 -0
- data/app/models/rails_connector/default_rating.rb +20 -0
- data/app/models/rails_connector/link_list.rb +30 -0
- data/app/views/cms/_comments.html.erb +44 -0
- data/app/views/cms/_index.html.erb +7 -0
- data/app/views/cms/_rating.html.erb +31 -0
- data/app/views/cms/index.html.erb +3 -0
- data/app/views/comments/_comment.html.erb +28 -0
- data/app/views/confirmation_mailer/register_confirmation.erb +5 -0
- data/app/views/confirmation_mailer/reset_password.erb +5 -0
- data/app/views/crm_form/_flash_messages.html.erb +11 -0
- data/app/views/crm_form/_form.html.erb +17 -0
- data/app/views/crm_form/confirmation.html.erb +3 -0
- data/app/views/crm_form/index.html.erb +5 -0
- data/app/views/crm_form/not_logged_in.html.erb +1 -0
- data/app/views/errors/403_forbidden.html.erb +3 -0
- data/app/views/errors/410_gone.html.erb +7 -0
- data/app/views/layouts/rails_connector/time_machine.html.erb +12 -0
- data/app/views/pdf/index.html.erb +7 -0
- data/app/views/pdf/index.xsl +1240 -0
- data/app/views/rails_connector/time_machine/index.html.erb +88 -0
- data/app/views/rss/_item.rss.builder +11 -0
- data/app/views/rss/index.rss.builder +11 -0
- data/app/views/search/_hit.html.erb +12 -0
- data/app/views/search/_hits.html.erb +11 -0
- data/app/views/search/_mini_panel.html.erb +4 -0
- data/app/views/search/_pagination.html.erb +5 -0
- data/app/views/search/_panel.html.erb +4 -0
- data/app/views/search/search.html.erb +12 -0
- data/app/views/seo_sitemap/show.xml.builder +16 -0
- data/app/views/user/_flash_messages.html.erb +11 -0
- data/app/views/user/edit.html.erb +6 -0
- data/app/views/user/edit_password.html.erb +11 -0
- data/app/views/user/forgot_password.html.erb +7 -0
- data/app/views/user/login.html.erb +15 -0
- data/app/views/user/new.html.erb +11 -0
- data/app/views/user/profile.html.erb +8 -0
- data/app/views/user/register_pending.html.erb +1 -0
- data/app/views/user/set_password.html.erb +14 -0
- data/config/cms_routes.rb +13 -0
- data/config/locales/de.rails_connector.controllers.yml +30 -0
- data/config/locales/de.rails_connector.errors.yml +11 -0
- data/config/locales/de.rails_connector.helpers.yml +9 -0
- data/config/locales/de.rails_connector.lib.yml +6 -0
- data/config/locales/de.rails_connector.models.yml +8 -0
- data/config/locales/de.rails_connector.views.yml +87 -0
- data/config/locales/en.rails_connector.controllers.yml +30 -0
- data/config/locales/en.rails_connector.errors.yml +10 -0
- data/config/locales/en.rails_connector.helpers.yml +9 -0
- data/config/locales/en.rails_connector.lib.yml +6 -0
- data/config/locales/en.rails_connector.models.yml +8 -0
- data/config/locales/en.rails_connector.views.yml +87 -0
- data/config/routes.rb +37 -0
- data/lib/generators/rails_connector/comments/comments_generator.rb +21 -0
- data/lib/generators/rails_connector/comments/templates/migration.rb +17 -0
- data/lib/generators/rails_connector/install/install_generator.rb +38 -0
- data/lib/generators/rails_connector/install/templates/initializers/rails_connector.rb +58 -0
- data/lib/generators/rails_connector/install/templates/local/configuration.rb +2 -0
- data/lib/generators/rails_connector/install/templates/obj_extensions.rb +25 -0
- data/lib/generators/rails_connector/ratings/ratings_generator.rb +21 -0
- data/lib/generators/rails_connector/ratings/templates/migration.rb +15 -0
- data/lib/infopark_rails_connector.rb +31 -0
- data/lib/obj_extensions.rb +6 -0
- data/lib/rails_connector/authenticable.rb +30 -0
- data/lib/rails_connector/cms_accessible.rb +114 -0
- data/lib/rails_connector/cms_dispatch_controller.rb +47 -0
- data/lib/rails_connector/cms_env.rb +55 -0
- data/lib/rails_connector/cms_test_request.rb +23 -0
- data/lib/rails_connector/commentable.rb +23 -0
- data/lib/rails_connector/configuration/google_analytics.rb +29 -0
- data/lib/rails_connector/configuration/pdf_generator.rb +15 -0
- data/lib/rails_connector/configuration/rss.rb +46 -0
- data/lib/rails_connector/configuration.rb +235 -0
- data/lib/rails_connector/core_extensions/time.rb +18 -0
- data/lib/rails_connector/core_extensions.rb +1 -0
- data/lib/rails_connector/crm.rb +282 -0
- data/lib/rails_connector/engine.rb +78 -0
- data/lib/rails_connector/fop.rb +18 -0
- data/lib/rails_connector/fop_on_rails/document/dom_tree.rb +42 -0
- data/lib/rails_connector/fop_on_rails/document/images.rb +34 -0
- data/lib/rails_connector/fop_on_rails/document/tables.rb +67 -0
- data/lib/rails_connector/fop_on_rails/document.rb +25 -0
- data/lib/rails_connector/fop_on_rails.rb +92 -0
- data/lib/rails_connector/googlebot_checker.rb +47 -0
- data/lib/rails_connector/html_string.rb +19 -0
- data/lib/rails_connector/infopark_base.rb +2 -0
- data/lib/rails_connector/link_resolvable.rb +9 -0
- data/lib/rails_connector/liquid_support/action_marker.rb +69 -0
- data/lib/rails_connector/liquid_support/field_value_drop.rb +22 -0
- data/lib/rails_connector/liquid_support/general_helper_tag.rb +44 -0
- data/lib/rails_connector/liquid_support/link_drop.rb +22 -0
- data/lib/rails_connector/liquid_support/liquid_template_handler.rb +162 -0
- data/lib/rails_connector/liquid_support/named_object_drop.rb +14 -0
- data/lib/rails_connector/liquid_support/obj_drop.rb +43 -0
- data/lib/rails_connector/liquid_support/obj_filters.rb +77 -0
- data/lib/rails_connector/liquid_support.rb +23 -0
- data/lib/rails_connector/markdown_string.rb +19 -0
- data/lib/rails_connector/rateable.rb +57 -0
- data/lib/rails_connector/seo.rb +52 -0
- data/lib/rails_connector/ses.rb +72 -0
- data/lib/rails_connector/string_tagging.rb +29 -0
- data/lib/rails_connector/syndicateable.rb +11 -0
- data/lib/search_request.rb +2 -0
- data/lib/tasks/check.rake +25 -0
- data/lib/tasks/cms_license_check.rake +17 -0
- metadata +489 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
#
|
3
|
+
# This controller provides an interface for generating PDFs from CMS objects.
|
4
|
+
# It has two modes: internal mode and external mode.
|
5
|
+
#
|
6
|
+
# =Internal mode
|
7
|
+
#
|
8
|
+
# In the internal mode the PDF generator comes with a ready-made action, <code>index</code>.
|
9
|
+
# You can customize this action and/or add your own custom actions.
|
10
|
+
#
|
11
|
+
# To add your own action you need to provide:
|
12
|
+
# - a controller action
|
13
|
+
# - an XML template
|
14
|
+
# - an XSL stylesheet
|
15
|
+
#
|
16
|
+
# The XML template must be named <code><em>ACTION_NAME</em>.html.erb</code> and the XSL stylesheet
|
17
|
+
# must be named <code><em>ACTION_NAME</em>.xsl</code>. Place these files into <code>RAILS_ROOT/app/views/pdf/</code>.
|
18
|
+
#
|
19
|
+
# Use the module <code>RailsConnector::FopOnRails</code> to generate the PDF.
|
20
|
+
# Inside your action, the XML template has already been rendered and can be referenced by means of <code>@xml_path</code>.
|
21
|
+
# The XSL stylesheet can be referenced by means of <code>@xsl_path</code>.
|
22
|
+
#
|
23
|
+
# In your ERb template you can use <code>@obj</code> to reference the CMS object and the <code>display_value</code> method to
|
24
|
+
# render its attributes:
|
25
|
+
# <h1><%= display_value(@obj.title) %></h1>
|
26
|
+
#
|
27
|
+
# The named route is <code>pdf_with_action</code>:
|
28
|
+
# <%= link_to('Generate custom PDF', pdf_with_action_path(:action => 'my_action', :id => 1234)) %>
|
29
|
+
# # This will produce <a href="/pdf/my_action/1234">Generate custom PDF</a>
|
30
|
+
#
|
31
|
+
# =External mode
|
32
|
+
#
|
33
|
+
# In the external mode the PDF generator has a named route <code>pdf_external</code>
|
34
|
+
# and is accessed through the URL <code>/pdf/external</code>.
|
35
|
+
#
|
36
|
+
# In order to produce a PDF file, the GET parameters <code>xml_url</code> and <code>xsl_url</code>
|
37
|
+
# need to be provided.
|
38
|
+
#
|
39
|
+
# Optional GET-parameters are:
|
40
|
+
# filename: string
|
41
|
+
# tidy: true or false (default is false)
|
42
|
+
#
|
43
|
+
# Example:
|
44
|
+
# curl -d "xml_url=http://example.com/test.xml&xsl_url=http://example.com/test.xsl" -g http://localhost:3000/pdf/external
|
45
|
+
#
|
46
|
+
# To allow a host to be the source for XML or XSL, add it to the so called "white list". Add
|
47
|
+
# following to <code>RAILS_ROOT/config/initializers/rails_connector.rb</code> to do that:
|
48
|
+
# RailsConnector::Configuration::PdfGenerator.host_whitelist(
|
49
|
+
# 'example1.com',
|
50
|
+
# 'example2.com',
|
51
|
+
# 'example3.com'
|
52
|
+
# )
|
53
|
+
#
|
54
|
+
# You can add as many hosts as you need. If no hosts have been added to the "white list", then the
|
55
|
+
# PDF generator will refuse to produce PDF files from any external source.
|
56
|
+
#
|
57
|
+
# If the host given through <code>xml_url</code> or <code>xsl_url</code> is not included in the
|
58
|
+
# "white list", then an error message will be rendered as inline text with response status "403
|
59
|
+
# Forbidden".
|
60
|
+
#
|
61
|
+
class DefaultPdfController < DefaultCmsController
|
62
|
+
# Returns false by default to exclude this controller from regular Obj dispatch.
|
63
|
+
# @see DefaultCmsController#use_for_obj_dispatch?
|
64
|
+
def self.use_for_obj_dispatch?
|
65
|
+
# If this method would to return true, an Obj with ObjClass "pdf" would be delivered by
|
66
|
+
# the PdfController as an actual generated Pdf, which would be surprising to most developers.
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
before_filter :dump_obj
|
71
|
+
before_filter :compute_xsl_path
|
72
|
+
before_filter :send_pdf
|
73
|
+
|
74
|
+
after_filter :cleanup_xml
|
75
|
+
|
76
|
+
#
|
77
|
+
# Generates a PDF from a CMS object.
|
78
|
+
#
|
79
|
+
# Takes a GET-parameter, <code>id</code>, to determine the object.
|
80
|
+
#
|
81
|
+
# As a default, the built-in XML template and XSL stylesheet will be used. You can replace them
|
82
|
+
# with the files <code>RAILS_ROOT/app/views/pdf/index.html.erb</code> and <code>RAILS_ROOT/app/views/pdf/index.xsl</code> respectively.
|
83
|
+
#
|
84
|
+
# By default, the PDF will contain the title and the body of the object.
|
85
|
+
# The PDF will be named <code><em>NAME_OF_THE_OBJECT</em>.pdf</code>.
|
86
|
+
#
|
87
|
+
# The named route is called <code>pdf</code> and is accessed through
|
88
|
+
# <code>/pdf/<em>OBJECT_ID</em></code>.
|
89
|
+
#
|
90
|
+
# Example:
|
91
|
+
#
|
92
|
+
# <%= link_to 'Generate PDF', pdf_path(@obj) %>
|
93
|
+
# # This will generate a PDF containing the title and the body of the current object
|
94
|
+
#
|
95
|
+
def index
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def send_pdf
|
101
|
+
send_file(
|
102
|
+
FopOnRails.generate_pdf(@xml_path, @xsl_path),
|
103
|
+
:filename => "#{@obj.name}.pdf",
|
104
|
+
:type => 'application/pdf'
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def dump_obj
|
111
|
+
base_folder = Rails.root + "tmp"
|
112
|
+
FileUtils.mkdir_p(base_folder)
|
113
|
+
@xml_path = File.join(base_folder, "#{Time.now.to_f}_#{$$}")
|
114
|
+
data = render_to_string(:controller => 'pdf', :action => action_name, :layout => false)
|
115
|
+
File.open(@xml_path, 'w') do |f|
|
116
|
+
f.write(data)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def compute_xsl_path
|
121
|
+
@xsl_path = nil
|
122
|
+
view_paths.each do |view_path|
|
123
|
+
xsl_path = "#{view_path}/#{controller_name}/#{action_name}.xsl"
|
124
|
+
if File.exist?(xsl_path)
|
125
|
+
@xsl_path = xsl_path
|
126
|
+
return
|
127
|
+
end
|
128
|
+
end
|
129
|
+
raise 'No XSL template found' unless @xsl_path
|
130
|
+
end
|
131
|
+
|
132
|
+
def cleanup_xml
|
133
|
+
FileUtils.rm_rf(@xml_path)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
#
|
3
|
+
# This controller provides an interface for rating CMS objects.
|
4
|
+
#
|
5
|
+
# =Before Filters
|
6
|
+
# <tt>load_object</tt>: finds the Obj instance using <tt>params[:obj_id]</tt>
|
7
|
+
# <tt>ensure_object_is_rateable</tt>: renders nothing unless <tt>@obj.allow_rating?</tt> AND <tt>user_has_already_rated?(@obj.id)</tt> return <tt>true</tt>.
|
8
|
+
#
|
9
|
+
# =Hooks
|
10
|
+
#
|
11
|
+
# <tt>after_create</tt>: redefine this method in your application in order to specify additional functionality that should occur after a rating has been created.
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
#
|
15
|
+
# class RatingsController < RailsConnector::DefaultRatingsController
|
16
|
+
# private
|
17
|
+
# def after_create
|
18
|
+
# # * send an email
|
19
|
+
# # * create an inquiry in the OMC
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
class DefaultRatingsController < ApplicationController
|
23
|
+
|
24
|
+
before_filter :load_object
|
25
|
+
before_filter :ensure_object_is_rateable, :only => [:rate]
|
26
|
+
before_filter :ensure_admin, :only => :reset
|
27
|
+
|
28
|
+
layout nil
|
29
|
+
|
30
|
+
# Rate a CMS object.
|
31
|
+
def rate
|
32
|
+
respond_to do |format|
|
33
|
+
format.html do
|
34
|
+
score = params[:score].to_i
|
35
|
+
if @obj.rate(score)
|
36
|
+
store_rating_in_session(@obj.id, score)
|
37
|
+
after_create
|
38
|
+
end
|
39
|
+
render :partial => "cms/rating"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Reset rating for a CMS object.
|
45
|
+
def reset
|
46
|
+
respond_to do |format|
|
47
|
+
format.html do
|
48
|
+
@obj.reset_rating
|
49
|
+
store_rating_in_session(@obj.id, nil)
|
50
|
+
redirect_to :back
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def after_create;end
|
58
|
+
|
59
|
+
def load_object
|
60
|
+
@obj = Obj.find(params[:id])
|
61
|
+
end
|
62
|
+
|
63
|
+
def ensure_object_is_rateable
|
64
|
+
render(:nothing => true) if (!@obj.allow_rating? || user_has_already_rated?(@obj.id))
|
65
|
+
unless @obj.allow_anonymous_rating? or logged_in?
|
66
|
+
render '/errors/403_forbidden', :status => 403
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def user_has_already_rated?(obj_id)
|
71
|
+
session[:rated_objs] && session[:rated_objs][obj_id]
|
72
|
+
end
|
73
|
+
|
74
|
+
def store_rating_in_session(obj_id, score)
|
75
|
+
session[:rated_objs] ||= {}
|
76
|
+
session[:rated_objs][obj_id] = score
|
77
|
+
end
|
78
|
+
|
79
|
+
def ensure_admin
|
80
|
+
render("errors/403_forbidden", :status => 403) unless admin?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
#
|
3
|
+
# This class provides a default controller implementation for rendering an RSS feed.
|
4
|
+
# It should be customized by subclassing.
|
5
|
+
#
|
6
|
+
# The RSS feature assumes that you have a root object specified whose direct children will be used as feed entries.
|
7
|
+
#
|
8
|
+
# Specify the RSS root in
|
9
|
+
# <code><em>RAILS_ROOT</em>/config/initializers/rails_connector.rb</code>:
|
10
|
+
# RailsConnector::Configuration::Rss.root = lambda { NamedLink.get_object('news') }
|
11
|
+
class DefaultRssController < DefaultCmsController
|
12
|
+
#
|
13
|
+
# This action renders the built-in RSS feed.
|
14
|
+
#
|
15
|
+
# To customize feed's layout, override either this method, or the apropriate view.
|
16
|
+
#
|
17
|
+
def index
|
18
|
+
respond_to do |format|
|
19
|
+
format.rss
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def load_object # :nodoc:
|
26
|
+
@obj = Configuration::Rss.root
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'will_paginate'
|
2
|
+
|
3
|
+
module RailsConnector
|
4
|
+
|
5
|
+
# This class provides a default controller implementation for searching.
|
6
|
+
# It should be customized by subclassing.
|
7
|
+
class DefaultSearchController < ApplicationController
|
8
|
+
class_attribute :options
|
9
|
+
self.options = {:limit => 10}
|
10
|
+
|
11
|
+
# Fetches search hits and paginates them.
|
12
|
+
# In case of an error, flashes appropriate error messages.
|
13
|
+
#
|
14
|
+
# For use in views, hits are stored in the <tt>@hits</tt> variable.
|
15
|
+
# Pagination is done using the limit option (defaults to 10).
|
16
|
+
# You can change that limit by configuring
|
17
|
+
# <tt>RailsConnector::Configuration.search_options = {:limit => X}</tt>.
|
18
|
+
#
|
19
|
+
# To customize the pagination, you should subclass DefaultSearchController:
|
20
|
+
#
|
21
|
+
# class SearchController < RailsConnector::DefaultSearchController
|
22
|
+
# def search
|
23
|
+
# # What this method should do:
|
24
|
+
# # * Initialize a SearchRequest obj
|
25
|
+
# # * Paginate the results
|
26
|
+
# # * Fill the @hits variable for your views
|
27
|
+
# # * Flash on errors
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
def search
|
31
|
+
unless (@query = params[:q]).blank?
|
32
|
+
@hits = WillPaginate::Collection.create(current_page, options[:limit]) do |pager|
|
33
|
+
result = SearchRequest.new(@query, options.merge(:offset => pager.offset)).fetch_hits
|
34
|
+
pager.replace(result)
|
35
|
+
pager.total_entries = result.total_hits
|
36
|
+
end
|
37
|
+
else
|
38
|
+
flash.now[:errors] = I18n.t(:"rails_connector.controllers.search.specify_query")
|
39
|
+
end
|
40
|
+
rescue SES::SearchError => e
|
41
|
+
logger.error(e)
|
42
|
+
flash.now[:errors] = I18n.t(:"rails_connector.controllers.search.try_another_key")
|
43
|
+
rescue Errno::ECONNREFUSED, Errno::EAFNOSUPPORT
|
44
|
+
flash.now[:errors] = I18n.t(:"rails_connector.controllers.search.search_disabled")
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# This is just a convenience wrapper so the +options+ hash can be
|
50
|
+
# accessed easily from an instance of this class.
|
51
|
+
def options
|
52
|
+
self.class.options
|
53
|
+
end
|
54
|
+
|
55
|
+
def current_page
|
56
|
+
[params[:page].to_i, 1].max
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
require 'recaptcha'
|
2
|
+
require 'active_resource/exceptions'
|
3
|
+
|
4
|
+
module RailsConnector
|
5
|
+
|
6
|
+
# This class provides a default controller implementation for user functionality.
|
7
|
+
# It should be customized by subclassing.
|
8
|
+
#
|
9
|
+
# To change how all actions contacting the WebCRM behave in case of an WebCRM error,
|
10
|
+
# override +on_crm_error+ in your subclassed controller. See Crm::Callbacks for details.
|
11
|
+
#
|
12
|
+
# To override what attributes are writable by the user when registering or editing profiles,
|
13
|
+
# use +editable_attributes_on_register+ and +editable_attributes_on_edit+, respectively.
|
14
|
+
# This can be done in your <tt>rails_connector.rb</tt> or in +UserController+ directly.
|
15
|
+
#
|
16
|
+
# By default, users can submit their first name, last name, email and company name.
|
17
|
+
class DefaultUserController < ApplicationController
|
18
|
+
|
19
|
+
before_filter :check_editable_attribute_configuration
|
20
|
+
before_filter :redirect_to_login_unless_logged_in, :only => [
|
21
|
+
:edit, :edit_password, :profile
|
22
|
+
]
|
23
|
+
before_filter :check_recaptcha_keypair
|
24
|
+
around_filter :handle_crm_errors
|
25
|
+
|
26
|
+
cattr_accessor :editable_attributes_on_register, :editable_attributes_on_edit
|
27
|
+
self.editable_attributes_on_register = {
|
28
|
+
:contact => [:gender, :first_name, :last_name, :email, :phone, :language],
|
29
|
+
}
|
30
|
+
self.editable_attributes_on_edit = {
|
31
|
+
:contact => [:first_name, :last_name, :email, :phone, :language],
|
32
|
+
}
|
33
|
+
|
34
|
+
include Crm::Localizable
|
35
|
+
include Crm::Sanitization
|
36
|
+
include Crm::Callbacks
|
37
|
+
include ReCaptcha::AppHelper
|
38
|
+
|
39
|
+
def self.store_user_attrs_in_session=(fields)
|
40
|
+
raise %Q{
|
41
|
+
DefaultUserController doesn't maintain which fields are stored in the session anymore.
|
42
|
+
Please use RailsConnector::Configuration.store_user_attrs_in_session instead.
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
# Displays a profile page containing links to all available actions
|
47
|
+
def profile
|
48
|
+
end
|
49
|
+
|
50
|
+
# Logs a CRM user in.
|
51
|
+
#
|
52
|
+
# After successful login, user attributes are stored in <tt>session[:user]</tt>.
|
53
|
+
#
|
54
|
+
# To change which fields are stored in the session use
|
55
|
+
# +RailsConnector::Configuration.store_user_attrs_in_session+.
|
56
|
+
#
|
57
|
+
# Use +current_user+ for a Contact object of the attributes stored in the session.
|
58
|
+
#
|
59
|
+
# The user will be redirected to the path given in the return_to param. If no
|
60
|
+
# return_to param is set, the user will be redirected to the profile page.
|
61
|
+
#
|
62
|
+
# If you merely want to change what happens before or after a user is authenticated,
|
63
|
+
# do not override this method but override +before_authenticate+ or +after_authenticate+.
|
64
|
+
def login
|
65
|
+
if request.post?
|
66
|
+
@user = Infopark::Crm::Contact.new(params[:user] || {:login => nil, :password => nil})
|
67
|
+
before_authenticate
|
68
|
+
@user = Infopark::Crm::Contact.authenticate(@user.login, @user.password)
|
69
|
+
if @user
|
70
|
+
after_authenticate
|
71
|
+
flash[:notice] = tcon('login_successful')
|
72
|
+
self.current_user = @user
|
73
|
+
redirect_to params[:return_to].blank? ?
|
74
|
+
user_path(:action => 'profile') :
|
75
|
+
params[:return_to]
|
76
|
+
else
|
77
|
+
flash.now[:error] = tcon('login_failed')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
rescue Infopark::Crm::AuthenticationFailed, ActiveResource::ResourceInvalid
|
81
|
+
flash.now[:error] = tcon('login_failed')
|
82
|
+
ensure
|
83
|
+
@user.password = nil if @user
|
84
|
+
end
|
85
|
+
|
86
|
+
# Logs the user out by setting <tt>session[:user]</tt> to +nil+.
|
87
|
+
#
|
88
|
+
# To change the behavior before or after invalidating the session,
|
89
|
+
# override +before_logout+ or +after_logout+.
|
90
|
+
def logout
|
91
|
+
before_logout
|
92
|
+
self.current_user = nil
|
93
|
+
after_logout
|
94
|
+
redirect_to params[:return_to].blank? ? root_path : params[:return_to]
|
95
|
+
end
|
96
|
+
|
97
|
+
# Creates a WebCRM user.
|
98
|
+
#
|
99
|
+
# The user login is automatically set to his/her e-mail.
|
100
|
+
#
|
101
|
+
# If you merely want to change what happens before or after a user is registered,
|
102
|
+
# do not override this method but override +before_register+ or +after_register+.
|
103
|
+
def new
|
104
|
+
@user = Infopark::Crm::Contact.new
|
105
|
+
# Load some default attributes so that form_for is working
|
106
|
+
@user.load(Crm::CONTACT_DEFAULT_ATTRS.merge(sanitize_user_params(params[:user],
|
107
|
+
self.class.editable_attributes_on_register)))
|
108
|
+
if request.post?
|
109
|
+
unless validate_recap(params, @user.errors)
|
110
|
+
raise ActiveResource::ResourceInvalid, "captcha failed"
|
111
|
+
end
|
112
|
+
before_register
|
113
|
+
register
|
114
|
+
after_register
|
115
|
+
redirect_to(:action => "register_pending")
|
116
|
+
end
|
117
|
+
rescue ActiveResource::ResourceInvalid
|
118
|
+
flash.now[:error] = tcon('registration_failed')
|
119
|
+
end
|
120
|
+
|
121
|
+
def register_pending
|
122
|
+
end
|
123
|
+
|
124
|
+
# Lets the user change his/her user details.
|
125
|
+
def edit
|
126
|
+
@user = Infopark::Crm::Contact.find(current_user.id)
|
127
|
+
if request.post? || request.put?
|
128
|
+
@user.load(sanitize_user_params(params[:user], self.class.editable_attributes_on_edit))
|
129
|
+
@user.save
|
130
|
+
flash[:notice] = tcon('edit_successful')
|
131
|
+
redirect_to(:action => 'profile')
|
132
|
+
end
|
133
|
+
rescue ActiveResource::ResourceInvalid
|
134
|
+
flash.now[:error] = tcon('edit_failed')
|
135
|
+
end
|
136
|
+
|
137
|
+
# Lets the user change his/her password.
|
138
|
+
#
|
139
|
+
# Validates the new password using +validate_edit_password_params_for+.
|
140
|
+
def edit_password
|
141
|
+
if request.post?
|
142
|
+
validate_edit_password_params_for(params[:user])
|
143
|
+
@user = Infopark::Crm::Contact.authenticate(current_user.login, params[:user][:old_password])
|
144
|
+
@user.password_set(params[:user][:new_password])
|
145
|
+
flash[:notice] = tcon('edit_password_successful')
|
146
|
+
redirect_to(:action => "profile")
|
147
|
+
end
|
148
|
+
rescue ActiveResource::ResourceInvalid, Infopark::Crm::AuthenticationFailed
|
149
|
+
flash.now[:error] = tcon('edit_password_failed')
|
150
|
+
end
|
151
|
+
|
152
|
+
# Lets the user request a new password (double opt-in).
|
153
|
+
#
|
154
|
+
# Uses the +ConfirmationMailer+ for sending out the confirmation message.
|
155
|
+
def forgot_password
|
156
|
+
if request.post?
|
157
|
+
user = Infopark::Crm::Contact.search(:params => {:login => params[:user][:login]}).first
|
158
|
+
if user
|
159
|
+
confirmation_link = set_password_url_for(user)
|
160
|
+
ConfirmationMailer.reset_password(user.email, confirmation_link).deliver
|
161
|
+
flash[:notice] = tcon('reset_password_successful')
|
162
|
+
redirect_to(:action => "forgot_password")
|
163
|
+
else
|
164
|
+
flash.now[:error] = tcon('request_password_failed')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def set_password
|
170
|
+
if request.get? && params[:token].blank?
|
171
|
+
flash[:error] = tcon('token_url_invalid')
|
172
|
+
elsif request.post?
|
173
|
+
if params[:user][:new_password].blank?
|
174
|
+
flash.now[:error] = tcon('password_cannot_be_empty')
|
175
|
+
elsif params[:user][:new_password] != params[:user][:new_password_confirm]
|
176
|
+
flash.now[:error] = tcon('password_does_not_match_confirmation')
|
177
|
+
else
|
178
|
+
Infopark::Crm::Contact.password_set(params[:user][:new_password], params[:user][:token])
|
179
|
+
flash[:notice] = tcon('password_set')
|
180
|
+
redirect_to(:action => 'login')
|
181
|
+
end
|
182
|
+
end
|
183
|
+
rescue ActiveResource::ResourceNotFound => e
|
184
|
+
flash[:error] = tcon('set_password_failed')
|
185
|
+
end
|
186
|
+
|
187
|
+
protected
|
188
|
+
|
189
|
+
def check_editable_attribute_configuration
|
190
|
+
raise RuntimeError if editable_attributes_on_edit[:contact].nil? ||
|
191
|
+
editable_attributes_on_register[:contact].nil?
|
192
|
+
rescue
|
193
|
+
raise ConfigurationError, "editable_attributes in UserController is not configured correctly"
|
194
|
+
end
|
195
|
+
|
196
|
+
def register
|
197
|
+
if @user.email.blank?
|
198
|
+
@user.errors.add(:base, tcon('email_blank'))
|
199
|
+
raise ActiveResource::ResourceInvalid.new("E-mail can't be blank")
|
200
|
+
end
|
201
|
+
@user.login = @user.email
|
202
|
+
@user.save!
|
203
|
+
confirmation_link = set_password_url_for(@user)
|
204
|
+
ConfirmationMailer.register_confirmation(@user.email, confirmation_link).deliver
|
205
|
+
flash[:notice] = tcon('registration_successful_awaiting_confirmation')
|
206
|
+
end
|
207
|
+
|
208
|
+
def tcon(x)
|
209
|
+
t("rails_connector.controllers.user.#{x}")
|
210
|
+
end
|
211
|
+
|
212
|
+
ALL_CRM_ERRORS = [
|
213
|
+
Errno::ECONNREFUSED,
|
214
|
+
ActiveResource::ForbiddenAccess,
|
215
|
+
ActiveResource::UnauthorizedAccess,
|
216
|
+
ActiveResource::BadRequest
|
217
|
+
]
|
218
|
+
|
219
|
+
# invoke user defined callback when an error related to WebCRM occurs
|
220
|
+
def handle_crm_errors
|
221
|
+
yield
|
222
|
+
rescue *ALL_CRM_ERRORS => e
|
223
|
+
on_crm_error(e)
|
224
|
+
default_render unless performed?
|
225
|
+
end
|
226
|
+
|
227
|
+
# Filter to force users to login by redirecting.
|
228
|
+
def redirect_to_login_unless_logged_in
|
229
|
+
redirect_to login_path unless logged_in?
|
230
|
+
end
|
231
|
+
|
232
|
+
# Checks if constants RCC_PUB and RCC_PRIV are set (for reCaptcha)
|
233
|
+
#
|
234
|
+
# Used as a filter in this controller.
|
235
|
+
def check_recaptcha_keypair
|
236
|
+
unless Object.const_defined?(:RCC_PUB) && Object.const_defined?(:RCC_PRIV)
|
237
|
+
raise RuntimeError, <<-EOS
|
238
|
+
|
239
|
+
reCaptcha requires the constants RCC_PUB and RCC_PRIV to be set.
|
240
|
+
Please sign up for the reCaptcha webservice if you haven't already done so.
|
241
|
+
|
242
|
+
Then set your public key in RCC_PUB and your private key in RCC_PRIV.
|
243
|
+
EOS
|
244
|
+
end
|
245
|
+
true
|
246
|
+
end
|
247
|
+
|
248
|
+
# Validates the password for a given user.
|
249
|
+
#
|
250
|
+
# Used by #edit_password.
|
251
|
+
def validate_edit_password_params_for(params)
|
252
|
+
if params[:new_password].empty? || params[:new_password] != params[:new_password_confirm]
|
253
|
+
raise ActiveResource::ResourceInvalid.new(
|
254
|
+
"password is empty or does not match confirmation"
|
255
|
+
)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# Generates a URL for password confirmation.
|
260
|
+
def set_password_url_for(user)
|
261
|
+
url_for(
|
262
|
+
:action => "set_password",
|
263
|
+
:token => user.password_request(:params => {:only_get_token => true})
|
264
|
+
)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
class PdfExternalController < ApplicationController # :nodoc: all
|
3
|
+
skip_before_filter :verify_authenticity_token
|
4
|
+
before_filter :validate_inputs
|
5
|
+
|
6
|
+
def index
|
7
|
+
send_file(
|
8
|
+
FopOnRails.generate_pdf(
|
9
|
+
params[:xml_url],
|
10
|
+
params[:xsl_url],
|
11
|
+
params[:tidy]
|
12
|
+
),
|
13
|
+
:filename => "#{params[:filename] || 'output'}.pdf",
|
14
|
+
:type => 'application/pdf'
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def validate_inputs
|
21
|
+
validate_input('xml', params['xml_url'])
|
22
|
+
validate_input('xsl', params['xsl_url'])
|
23
|
+
validate_hosts
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate_input(type, url)
|
27
|
+
unless url and valid_url?(url)
|
28
|
+
raise "Invalid #{type} input URL: #{url || 'empty'}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid_url?(url)
|
33
|
+
begin
|
34
|
+
URI.parse(url)
|
35
|
+
rescue URI::InvalidURIError
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def validate_hosts
|
42
|
+
xml_host, xsl_host = URI.parse(params['xml_url']).host, URI.parse(params['xsl_url']).host
|
43
|
+
bad_host = [xml_host, xsl_host].detect do |host|
|
44
|
+
!Configuration::PdfGenerator.host_allowed?(host)
|
45
|
+
end
|
46
|
+
if bad_host
|
47
|
+
render(
|
48
|
+
:status => 403,
|
49
|
+
:text => I18n.t(:"rails_connector.controllers.pdf_external.host_not_allowed", :host => bad_host)
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
|
3
|
+
class TimeMachineController < ApplicationController #:nodoc:
|
4
|
+
|
5
|
+
protect_from_forgery :except => :set_preview_time
|
6
|
+
|
7
|
+
before_filter :only_available_in_editor_mode
|
8
|
+
|
9
|
+
def index
|
10
|
+
@language = params[:language] || 'de'
|
11
|
+
@preview_time = session[:preview_time] || Time.now
|
12
|
+
end
|
13
|
+
|
14
|
+
# Set the preview time to the Time as specified by the parameter <tt>:preview_time</tt>.
|
15
|
+
def set_preview_time
|
16
|
+
if preview_time = params[:preview_time]
|
17
|
+
pt = Time.from_iso(preview_time)
|
18
|
+
pt = nil if pt <= Time.now
|
19
|
+
handle_request pt
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Resets the preview time, so <tt>Time::now</tt> will be used as preview time afterwards.
|
24
|
+
def reset_preview_time
|
25
|
+
handle_request nil
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def handle_request(preview_time)
|
31
|
+
session[:preview_time] = preview_time
|
32
|
+
if request.xhr?
|
33
|
+
render :js => "window.location.reload();"
|
34
|
+
else
|
35
|
+
render :nothing => true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def only_available_in_editor_mode
|
40
|
+
unless Configuration.editor_interface_enabled?
|
41
|
+
render :template => 'errors/403_forbidden', :status => 403, :content_type => Mime::HTML
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|