renderer.rb 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. class NotificationFactory::Renderer
  2. =begin
  3. examples how to use
  4. message_subject = NotificationFactory::Renderer.new(
  5. {
  6. ticket: Ticket.first,
  7. },
  8. 'de-de',
  9. 'some template <b>#{ticket.title}</b> {config.fqdn}',
  10. false
  11. ).render
  12. message_body = NotificationFactory::Renderer.new(
  13. {
  14. ticket: Ticket.first,
  15. },
  16. 'de-de',
  17. 'some template <b>#{ticket.title}</b> #{config.fqdn}',
  18. ).render
  19. =end
  20. def initialize(objects, locale, template, escape = true)
  21. @objects = objects
  22. @locale = locale || Setting.get('locale_default') || 'en-us'
  23. @template = NotificationFactory::Template.new(template, escape)
  24. @escape = escape
  25. end
  26. def render
  27. ERB.new(@template.to_s).result(binding)
  28. end
  29. # d - data of object
  30. # d('user.firstname', htmlEscape)
  31. def d(key, escape = nil)
  32. # do validaton, ignore some methodes
  33. return "\#{#{key} / not allowed}" if !data_key_valid?(key)
  34. # aliases
  35. map = {
  36. 'article.body' => 'article.body_as_text_with_quote.text2html',
  37. }
  38. if map[key]
  39. key = map[key]
  40. end
  41. # escape in html mode
  42. if escape
  43. no_escape = {
  44. 'article.body_as_html' => true,
  45. 'article.body_as_text_with_quote.text2html' => true,
  46. }
  47. if no_escape[key]
  48. escape = false
  49. end
  50. end
  51. value = nil
  52. object_methods = key.split('.')
  53. object_name = object_methods.shift
  54. # if no object is given, just return
  55. return '#{no such object}' if object_name.blank? # rubocop:disable Lint/InterpolationCheck
  56. object_refs = @objects[object_name] || @objects[object_name.to_sym]
  57. # if object is not in avalable objects, just return
  58. return "\#{#{object_name} / no such object}" if !object_refs
  59. # if content of method is a complex datatype, just return
  60. if object_methods.blank? && object_refs.class != String && object_refs.class != Float && object_refs.class != Integer
  61. return "\#{#{key} / no such method}"
  62. end
  63. object_methods_s = ''
  64. object_methods.each do |method_raw|
  65. method = method_raw.strip
  66. if object_methods_s != ''
  67. object_methods_s += '.'
  68. end
  69. object_methods_s += method
  70. if object_methods_s == ''
  71. value = "\#{#{object_name}.#{object_methods_s} / no such method}"
  72. break
  73. end
  74. # if method exists
  75. if !object_refs.respond_to?(method.to_sym)
  76. value = "\#{#{object_name}.#{object_methods_s} / no such method}"
  77. break
  78. end
  79. begin
  80. object_refs = object_refs.send(method.to_sym)
  81. rescue => e
  82. object_refs = "\#{#{object_name}.#{object_methods_s} / e.message}"
  83. end
  84. end
  85. placeholder = if !value
  86. object_refs
  87. else
  88. value
  89. end
  90. escaping(placeholder, escape)
  91. end
  92. # c - config
  93. # c('fqdn', htmlEscape)
  94. def c(key, escape = nil)
  95. config = Setting.get(key)
  96. escaping(config, escape)
  97. end
  98. # t - translation
  99. # t('yes', htmlEscape)
  100. def t(key, escape = nil)
  101. translation = Translation.translate(@locale, key)
  102. escaping(translation, escape)
  103. end
  104. # h - htmlEscape
  105. # h('fqdn', htmlEscape)
  106. def h(key)
  107. return key if !key
  108. CGI.escapeHTML(key.to_s)
  109. end
  110. private
  111. def escaping(key, escape)
  112. return key if escape == false
  113. return key if escape.nil? && !@escape
  114. h key
  115. end
  116. def data_key_valid?(key)
  117. return false if key =~ /`|\.(|\s*)(save|destroy|delete|remove|drop|update|create|new|all|where|find|raise|dump|rollback|freeze)/i && key !~ /(update|create)d_(at|by)/i
  118. true
  119. end
  120. end