mautic 2.3.3 → 2.3.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4499d4f66adb74f89f363f1407b0cf917728eaba2e10f9a48183a12ad14d8514
4
- data.tar.gz: 2165001c7af680d7f3c9929a1fff7f8d463d8396d9514370f50669d59ac5dcd1
3
+ metadata.gz: ffa1c03fd57447ef4b33050b2fea5150a9c4b2665675fdb0894f1a914c7e24af
4
+ data.tar.gz: 05be7f0b16e1a3e0a9f3c3adc0e89c3e3b1c0554afd122777fce06ec2ab1dad9
5
5
  SHA512:
6
- metadata.gz: 3a6de50ca1f0e1b51b0e7b4a547327351c0ac984e64dd23e48e7e55d20523fa6155b1d2aa0737110878e9af8dda916e17cb40ca9b0752d4b3d79033dbd1a76cf
7
- data.tar.gz: 8bf7ba6cbe4fe3903b09b2083dda2a9204d49ac2b0187e0bd053259c57b21db29c2aeadcacdce4261f570cd37d9b10e8dc28f6500463a75335fda29ca116b875
6
+ metadata.gz: 20100e7ada6a8715ffefe5d2210c4c4cdd20007e0f410ef9d66a192851deca4a86e4b4fb1e91e25a00ac639641d7210c2bf64cf1f8dec36b9476bc73edfd46cb
7
+ data.tar.gz: 9f6e8a2abcb4ac1e067420e88e1691a6fb0f63cc1ddb3ffaa1a0be8043985dd072735b2e1316c8e0a413dcde474e743c446ed65d2b815dc29da140866a820245
data/README.md CHANGED
@@ -88,6 +88,18 @@ mount Mautic::Engine => "/mautic"
88
88
  contact.save # => false
89
89
  contact.errors # => [{"code"=>400, "message"=>"email: This field is required.", "details"=>{"email"=>["This field is required."]}}]
90
90
  ```
91
+ Do not contact
92
+ ```ruby
93
+ contact.do_not_contact? # => false
94
+ contact.do_not_contact! message: "Some reason"
95
+ contact.do_not_contact? # => true
96
+ ```
97
+ Remove do not contact
98
+ ```ruby
99
+ contact.do_not_contact? # => true
100
+ contact.remove_do_not_contact!
101
+ contact.do_not_contact? # => false
102
+ ```
91
103
  Of course you can use more than contact: `assets`, `emails`, `companies`, `forms`, `points` ...
92
104
  ### Gem provides simple Mautic form submit
93
105
  There are two options of usage:
@@ -3,6 +3,7 @@ module Mautic
3
3
 
4
4
  alias_attribute :first_name, :firstname
5
5
  alias_attribute :last_name, :lastname
6
+
6
7
  def self.in(connection)
7
8
  Proxy.new(connection, endpoint, default_params: { search: '!is:anonymous' })
8
9
  end
@@ -11,16 +12,116 @@ module Mautic
11
12
  "#{firstname} #{lastname}"
12
13
  end
13
14
 
15
+ # @param [Hash] hash
16
+ # option hash [Integer] :id
17
+ # option hash [String] :firstName
18
+ # option hash [String] :lastName
19
+ def owner=(hash)
20
+ raise ArgumentError, "must be a hash !" unless hash.is_a?(Hash)
21
+
22
+ @table[:owner] = hash["id"]
23
+ @owner = hash
24
+ end
25
+
26
+ # @return [Hash]
27
+ # @example {id: 12, firstName: "Joe", lastName: "Doe"}
28
+ def owner
29
+ @owner || {}
30
+ end
31
+
32
+ # Assign mautic User ID as owner - for example for update author of contact
33
+ # @see https://developer.mautic.org/#edit-contact set owner
34
+ # @param [Integer] int
35
+ def owner_id=(int)
36
+ @table[:owner] = int
37
+ end
38
+
14
39
  def assign_attributes(source = nil)
15
40
  super
16
- self.attributes = {
17
- tags: (source['tags'] || []).collect { |t| Mautic::Tag.new(@connection, t) }.sort_by(&:name)
18
- } if source
41
+
42
+ if source
43
+ self.owner = source['owner'] || {}
44
+ self.attributes = {
45
+ tags: (source['tags'] || []).collect { |t| Mautic::Tag.new(@connection, t) }.sort_by(&:name),
46
+ doNotContact: source['doNotContact'] || [],
47
+ owner: owner['id'],
48
+ }
49
+ end
50
+ end
51
+
52
+ def to_mautic(data = @table)
53
+ data.delete(:doNotContact)
54
+ data.delete(:tags)
55
+ super(data)
19
56
  end
20
57
 
21
58
  def events
22
59
  @proxy_events ||= Proxy.new(connection, "contacts/#{id}/events", klass: "Mautic::Event")
23
60
  end
24
61
 
62
+ # @!group Do Not Contact
63
+ # @see https://developer.mautic.org/#add-do-not-contact
64
+
65
+ def do_not_contact?
66
+ doNotContact.present?
67
+ end
68
+
69
+ alias dnc? do_not_contact?
70
+
71
+ # @return [Array[Hash]]
72
+ def do_not_contact
73
+ return unless do_not_contact?
74
+
75
+ # Based on mautic docs => Contacts constants: Contacts::UNSUBSCRIBED (1), Contacts::BOUNCED (2), Contacts::MANUAL (3)
76
+ reason_list = { 1 => :unsubscribed, 2 => :bounced, 3 => :manual }
77
+ @do_not_contact ||= doNotContact.collect do |hsh|
78
+ { reason_list[hsh["reason"]] => hsh["comments"] }
79
+ end
80
+ end
81
+
82
+ def bounced?
83
+ do_not_contact? && !!do_not_contact.detect { |dnc| dnc.key?(:bounced) }
84
+ end
85
+
86
+ def unsubscribed?
87
+ do_not_contact? && !!do_not_contact.detect { |dnc| dnc.key?(:unsubscribed) }
88
+ end
89
+
90
+ def do_not_contact!(comments: '')
91
+ begin
92
+ json = @connection.request(:post, "api/contacts/#{id}/dnc/email/add", body: { comments: comments })
93
+ self.attributes = { doNotContact: json[endpoint.singularize]["doNotContact"] }
94
+ clear_changes
95
+ rescue ValidationError => e
96
+ self.errors = e.errors
97
+ end
98
+
99
+ self.errors.blank?
100
+ end
101
+
102
+ alias add_dnc do_not_contact!
103
+
104
+ def remove_do_not_contact!
105
+ begin
106
+ json = @connection.request(:post, "api/contacts/#{id}/dnc/email/remove", body: {})
107
+ self.attributes = { doNotContact: json[endpoint.singularize]["doNotContact"] }
108
+ clear_changes
109
+ rescue ValidationError => e
110
+ self.errors = e.errors
111
+ end
112
+
113
+ self.errors.blank?
114
+ end
115
+
116
+ alias remove_dnc remove_do_not_contact!
117
+
118
+ # !endgroup
119
+
120
+ private
121
+
122
+ def clear_change
123
+ super
124
+ remove_instance_variable :@do_not_contact
125
+ end
25
126
  end
26
127
  end
@@ -6,6 +6,10 @@ module Mautic
6
6
  tag
7
7
  end
8
8
 
9
+ def to_s
10
+ name
11
+ end
12
+
9
13
  def name=(name)
10
14
  self.tag = name
11
15
  end
@@ -11,12 +11,23 @@ module Mautic
11
11
 
12
12
  class RequestError < StandardError
13
13
 
14
- attr_reader :response, :errors
14
+ attr_reader :response, :errors, :request_url
15
15
 
16
16
  def initialize(response, message = nil)
17
17
  @errors ||= []
18
18
  @response = response
19
- json_body = JSON.parse(response.body) rescue {}
19
+ @request_url = response.response&.env&.url
20
+ body = if response.body.start_with? "<!DOCTYPE html>"
21
+ response.body.split("\n").last
22
+ else
23
+ response.body
24
+ end
25
+
26
+ json_body = begin
27
+ JSON.parse(body)
28
+ rescue JSON::ParserError
29
+ { "errors" => [{ "code" => response.status, "message" => body }] }
30
+ end
20
31
  message ||= Array(json_body['errors']).collect do |error|
21
32
  msg = error['code'].to_s
22
33
  msg << " (#{error['type']}):" if error['type']
@@ -25,7 +36,7 @@ module Mautic
25
36
  msg
26
37
  end.join(', ')
27
38
 
28
- super(message)
39
+ super("#{@request_url} => #{message}")
29
40
  end
30
41
 
31
42
  end
@@ -37,7 +48,11 @@ module Mautic
37
48
 
38
49
  def initialize(response, message = nil)
39
50
  @response = response
40
- json_body = JSON.parse(response.body) rescue {}
51
+ json_body = begin
52
+ JSON.parse(response.body)
53
+ rescue ParseError
54
+ {}
55
+ end
41
56
  @errors = Array(json_body['errors']).inject({}) { |mem, var| mem.merge!(var['details']); mem }
42
57
  message ||= @errors.collect { |field, msg| "#{field}: #{msg.join(', ')}" }.join('; ')
43
58
  super(response, message)
@@ -5,7 +5,8 @@ module Mautic
5
5
  config.generators do |g|
6
6
  g.test_framework :rspec, fixture: false
7
7
  end
8
-
8
+
9
+ # :nocov:
9
10
  initializer :append_migrations do |app|
10
11
  unless app.root.to_s.match root.to_s
11
12
  config.paths['db/migrate'].expanded.each do |expanded_path|
@@ -13,6 +14,7 @@ module Mautic
13
14
  end
14
15
  end
15
16
  end
17
+ # :nocov:
16
18
 
17
19
  end
18
20
  end
@@ -38,6 +38,7 @@ module Mautic
38
38
  end
39
39
 
40
40
  attr_reader :connection
41
+ attr_accessor :errors
41
42
 
42
43
  # @param [Mautic::Connection] connection
43
44
  def initialize(connection, hash = nil)
@@ -58,9 +59,10 @@ module Mautic
58
59
 
59
60
  def update(force = false)
60
61
  return false if changes.blank?
62
+
61
63
  begin
62
- json = @connection.request((force && :put || :patch), "api/#{endpoint}/#{id}/edit", { body: to_mautic })
63
- self.attributes = json[endpoint.singularize]
64
+ json = @connection.request((force && :put || :patch), "api/#{endpoint}/#{id}/edit", body: to_mautic)
65
+ assign_attributes json[endpoint.singularize]
64
66
  clear_changes
65
67
  rescue ValidationError => e
66
68
  self.errors = e.errors
@@ -69,10 +71,18 @@ module Mautic
69
71
  self.errors.blank?
70
72
  end
71
73
 
74
+ def update_columns(attributes = {})
75
+ json = @connection.request(:patch, "api/#{endpoint}/#{id}/edit", body: to_mautic(attributes))
76
+ assign_attributes json[endpoint.singularize]
77
+ clear_changes
78
+ rescue ValidationError => e
79
+ self.errors = e.errors
80
+ end
81
+
72
82
  def create
73
83
  begin
74
- json = @connection.request(:post, "api/#{endpoint}/#{id && "#{id}/"}new", { body: to_mautic })
75
- self.attributes = json[endpoint.singularize]
84
+ json = @connection.request(:post, "api/#{endpoint}/#{id && "#{id}/"}new", body: to_mautic)
85
+ assign_attributes json[endpoint.singularize]
76
86
  clear_changes
77
87
  rescue ValidationError => e
78
88
  self.errors = e.errors
@@ -106,8 +116,8 @@ module Mautic
106
116
  end
107
117
  end
108
118
 
109
- def to_mautic
110
- @table.each_with_object({}) do |(key,val), mem|
119
+ def to_mautic(data = @table)
120
+ data.each_with_object({}) do |(key, val), mem|
111
121
  mem[key] = val.is_a?(Array) ? val.join("|") : val
112
122
  end
113
123
  end
@@ -23,28 +23,20 @@ module Mautic
23
23
 
24
24
  def all(options = {}, &block)
25
25
  if options[:limit] == 'all'
26
-
27
26
  options.delete(:limit)
28
-
29
- records = results = where(options)
30
- total = @last_response['total'].to_i
31
- while records.any?
32
- records.each(&block) if block_given?
33
- break if results.size >= total
34
-
35
- records = where(options.merge(start: records.size))
36
- results.concat records
37
- end
27
+ limit_all(options, &block)
38
28
  else
39
29
  results = where(options)
40
30
  results.each { |i| yield i } if block_given?
31
+ results
41
32
  end
42
- results
43
33
  end
44
34
 
35
+ # @param [Hash] params
36
+ # @see https://developer.mautic.org
45
37
  def where(params = {})
46
38
  q = params.reverse_merge(@options[:default_params] || {})
47
- json = @connection.request(:get, "api/#{@endpoint}", { params: q })
39
+ json = @connection.request(:get, "api/#{@endpoint}", params: q)
48
40
  @count = json["total"].to_i
49
41
  @last_response = json
50
42
  json[data_name].collect do |id, attributes|
@@ -69,5 +61,22 @@ module Mautic
69
61
  @count = json["total"].to_i
70
62
  end
71
63
 
64
+ protected
65
+
66
+ # @param [Hash] options
67
+ # @option options (see #where)
68
+ def limit_all(options, &block)
69
+ records = results = where(options)
70
+ total = @last_response['total'].to_i
71
+ while records.any?
72
+ records.each(&block) if block_given?
73
+ break if results.size >= total
74
+
75
+ records = where(options.merge(start: records.size))
76
+ results.concat records
77
+ end
78
+ results
79
+ end
80
+
72
81
  end
73
82
  end
@@ -1,3 +1,3 @@
1
1
  module Mautic
2
- VERSION = '2.3.3'
2
+ VERSION = '2.3.8'
3
3
  end
@@ -1,6 +1,8 @@
1
1
  ENV['RAILS_ENV'] ||= 'test'
2
2
  require 'simplecov'
3
- SimpleCov.start
3
+ SimpleCov.start do
4
+ add_filter "/spec/"
5
+ end
4
6
 
5
7
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
6
8
  # Prevent database truncation if the environment is production
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mautic
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.3
4
+ version: 2.3.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukáš Pokorný
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-07 00:00:00.000000000 Z
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
222
  - !ruby/object:Gem::Version
223
223
  version: '0'
224
224
  requirements: []
225
- rubygems_version: 3.0.4
225
+ rubygems_version: 3.0.8
226
226
  signing_key:
227
227
  specification_version: 4
228
228
  summary: Ruby on Rails Mautic integration