saruman 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,19 +2,21 @@
2
2
 
3
3
  A ruby gem developed by jasonayre of bravenewwebdesign.com (site down currently), to make super complicated, ridiculous, time consuming things in Magento, e.g. creating a new extension, easy.
4
4
 
5
- ## NOTE: NOT EVERYTHING HAS BEEN TESTED, USE AT YOUR OWN RISK
5
+ ## NOTE: NOT EVERYTHING HAS BEEN THOROUGHLY TESTED, USE AT YOUR OWN RISK
6
6
 
7
- ### IF YOUR COMPUTER BLOWS UP, NOT MY FAULT. Probably make a new branch before attempting to use, ESPECIALLY if not creating a new extension.
7
+ ### IF YOUR COMPUTER BLOWS UP, NOT MY FAULT. Probably make a new branch before attempting to use!
8
8
 
9
9
  ## Installing
10
10
 
11
11
  gem install saruman
12
12
 
13
- Creating a new extension should be working. To do so, navigate to the root directory of your magento installation and call
13
+ Creating a new extension should be working. To do so, MAKE SURE YOU ARE IN THE ROOT DIRECTORY (containing app folder) of your magento installation and call
14
14
 
15
15
  saruman extension
16
16
 
17
- The wizard should take you through the rest of it. I would recommend adding an observer, choose event #3 (checkout_cart_update), and then after it's finished, add an item to your cart and watch the system log, to verify everything is working correctly (well not EVERYTHING, just the observer and general installation of the extension really)
17
+ The wizard should take you through the rest of it. I would recommend adding an observer, choose event #145 (checkout_cart_update), and then after it's finished, add an item to your cart and watch the system log, to verify everything is working correctly (well not EVERYTHING, just the observer and general installation of the extension really)
18
+
19
+ If you created a model, check your db for the new tables, along with the extension version in core_resource table
18
20
 
19
21
  ### A picture is worth a thousand words (or is it a million?)
20
22
 
@@ -22,23 +24,31 @@ However the phrase goes, its a lot of words, so here is an example of what my te
22
24
 
23
25
  ![Saruman Image example](/jasonayre/saruman/raw/master/doc_assets/saruman_extension_example.jpg)
24
26
 
25
- ### Creating the models
26
-
27
- You are able to create an unlimited number of models for your extension, and it is done in rails fashion. E.g, when you get to models part of wizard:
28
-
29
- title:string content:text active:boolean
27
+ ## Commands
30
28
 
31
- Will create the magento installer sql using the rails friendly syntax.
29
+ ### saruman extension
32
30
 
33
- ### Future stuff
31
+ saruman extension
32
+
33
+ Will guide you through the wizard process and help you build an extension. Will let you create an observer, model, helper for your new extension along with an installer.
34
34
 
35
- Technically I believe the model command is working, honestly haven't really tested it so I dont recommend using it. The idea behind this whole library is you will be able to do things like
35
+ ### saruman model
36
36
 
37
37
  saruman model
38
38
 
39
- And then the wizard will let you create any number of models, using a railsish syntax, which will create magento models for a specific extension. It will also create a new version upgrade, along with the resource models and what not.
39
+ Will let you create any number of models for the specified magento extension. You must type the fields using same syntax rails uses. e.x.
40
40
 
41
- The coolest part and hardest part to get right, is I'm actually reading the config files of the magento extension, and appending the new data declarations for the models and what not, in an attempt to really simplify the creation of magento extensions. (work in progress, you can try it for now but no promises nothing will break)
41
+ title:string content:text active:boolean
42
+
43
+ When creating models, it is assumed that you will be creating a new version of the extension. Therefore, a upgrade file is created with the SQL for all of your new models, along with the appropriately named new version.
44
+ NOTE: I couldn't remember whether Magento even allows anything but 0.0.1 (3 digits sep by period) syntax, so things will probably break if that is not the case, and you don't have the 3 digit version syntax on your extension (writing this super fast so dont have time to check.)
42
45
 
46
+ ### saruman observer
43
47
 
48
+ saruman observer
49
+
50
+ Will create a new observer file with an unlimited amount of events you wish to observe. I also parsed a document containing most of the observer events in magento version 1.5ish I believe, so there are about 300 events to choose from, no guarantees that they all work or are up to date. Just type the number of the observer event youd like to observer, rinse and repeat until you are finished (note that it will create all the observer events into one observer.php file so it will overwrite if you have an observer already.)
51
+
52
+ ### Future stuff
44
53
 
54
+ Controllers, helpers, more stuff. I'll post a screencast of how to use it as well, sometime in near future.
data/lib/saruman/cli.rb CHANGED
@@ -8,11 +8,11 @@ module Saruman
8
8
  desc "extension", "Creates a new magento extension"
9
9
  def extension
10
10
  options = Hash.new
11
-
11
+ options[:command] = __method__
12
12
  options[:namespace] = ask("Enter extension namespace:") { |q| q.default = "Saruman" }
13
13
  options[:name] = ask("Enter extension name:") { |q| q.default = "Wizard" }
14
14
  options[:author] = ask("Author of extension:") { |q| q.default = "Jason Ayre www.bravenewwebdesign.com" }
15
- options[:version] = ask("Version number (default - 0.0.1):") { |q| q.default = "0.0.1" }
15
+ options[:version] = ask("Version number (Format - 0.0.1):") { |q| q.default = "0.0.1" }
16
16
 
17
17
  say("Would you like me to create an observer?")
18
18
  choose do |menu|
@@ -21,18 +21,25 @@ module Saruman
21
21
  end
22
22
 
23
23
  if(options[:observer])
24
+
24
25
  say("Choose the events you would like to observe")
25
26
  begin
27
+
26
28
  choose do |menu|
27
29
  if(options[:observer_events]).nil?
28
30
  options[:observer_events] = Array.new
29
31
  end
30
- menu.choice(:catalogrule_before_apply) { options[:observer_events].push(:catalog_before_apply) }
31
- menu.choice(:catalogrule_after_apply) { options[:observer_events].push(:catalog_after_apply) }
32
- menu.choice(:checkout_cart_save_after) { options[:observer_events].push(:checkout_cart_save_after) }
32
+ if @observer_menu_builder.nil?
33
+ @observer_menu_builder = Saruman::ObserverMenuBuilder.new(menu)
34
+ else
35
+ @observer_menu_builder.display_choices(menu)
36
+ end
37
+
33
38
  end
34
39
  end while agree("Observe another event?")
35
40
 
41
+ options[:observer_events] = @observer_menu_builder.decisions
42
+
36
43
  end
37
44
 
38
45
  say("Would you like me to create a model?")
@@ -41,16 +48,16 @@ module Saruman
41
48
  menu.choice(:no) { options[:model] = false }
42
49
  end
43
50
 
44
- if(options[:model])
45
-
46
- if(options[:models]).nil?
47
- options[:models] = Array.new
48
- end
49
-
50
- begin
51
- question = Saruman::ModelBuilder.new
52
- options[:models] << question.output
53
- end while agree("Create another model?")
51
+ if(options[:model])
52
+
53
+ if(options[:models]).nil?
54
+ options[:models] = Array.new
55
+ end
56
+
57
+ begin
58
+ question = Saruman::ModelBuilder.new
59
+ options[:models] << question.output
60
+ end while agree("Create another model?")
54
61
 
55
62
  end
56
63
 
@@ -61,28 +68,61 @@ module Saruman
61
68
  end
62
69
 
63
70
  Saruman::Generators::Extension.start([options])
64
-
71
+
72
+ if options[:model]
73
+ Saruman::Generators::Model.start([options])
74
+ end
75
+
65
76
  end
66
77
 
67
78
  desc "model", "Creates a new magento model"
68
79
  def model
69
80
  options = Hash.new
81
+ options[:command] = __method__
70
82
  options[:namespace] = ask("Enter extension namespace:") { |q| q.default = "Saruman" }
71
83
  options[:name] = ask("Enter extension name:") { |q| q.default = "Wizard" }
72
84
 
73
- if(options[:models]).nil?
74
- options[:models] = Array.new
75
- end
76
-
77
- begin
78
- question = Saruman::ModelBuilder.new
79
- options[:models] << question.output
80
- end while agree("Create another model?")
81
-
85
+ if(options[:models]).nil?
86
+ options[:models] = Array.new
87
+ end
82
88
 
89
+ begin
90
+ question = Saruman::ModelBuilder.new
91
+ options[:models] << question.output
92
+ end while agree("Create another model?")
93
+
83
94
  Saruman::Generators::Model.start([options])
84
95
 
85
- end
96
+ end
97
+
98
+ desc "observer", "Creates a new observer for an extension"
99
+ def observer
100
+ options = Hash.new
101
+ options[:command] = __method__
102
+ options[:namespace] = ask("Enter extension namespace:") { |q| q.default = "Saruman" }
103
+ options[:name] = ask("Enter extension name:") { |q| q.default = "Wizard" }
104
+
105
+ say("Choose the events you would like to observe")
106
+ begin
107
+
108
+ choose do |menu|
109
+ if(options[:observer_events]).nil?
110
+ options[:observer_events] = Array.new
111
+ end
112
+ if @observer_menu_builder.nil?
113
+ @observer_menu_builder = Saruman::ObserverMenuBuilder.new(menu)
114
+ else
115
+ @observer_menu_builder.display_choices(menu)
116
+ end
117
+
118
+ end
119
+ end while agree("Observe another event?")
120
+
121
+ options[:observer_events] = @observer_menu_builder.decisions
122
+
123
+ Saruman::Generators::Observer.start([options])
124
+
125
+ end
86
126
 
87
127
  end
88
128
 
@@ -35,18 +35,6 @@
35
35
  <global>
36
36
  <% if model? %>
37
37
  <models>
38
- <<%= extension_name_lower %>>
39
- <class><%= model_klass_name %></class>
40
- <resourceModel><%= resource_model_name_lower %></resourceModel>
41
- </<%= extension_name_lower %>>
42
- <<%= resource_model_name_lower %>>
43
- <class><%= resource_model_klass_name %></class>
44
- <entities>
45
- <% models.each do |model| %>
46
- <<%= model[:model_name_lower] %>><table><%= model[:model_table_name] %></table></<%= model[:model_name_lower] %>>
47
- <% end %>
48
- </entities>
49
- </<%= resource_model_name_lower %>>
50
38
  </models>
51
39
  <resources>
52
40
  <<%= extension_name_lower %>_setup>
@@ -5,6 +5,7 @@ module Saruman
5
5
  module Generators
6
6
  class Extension < Thor::Group
7
7
  include Thor::Actions
8
+ include Saruman::Base
8
9
  argument :arguments, :type => :hash
9
10
 
10
11
  def self.source_root
@@ -35,132 +36,112 @@ module Saruman
35
36
  end
36
37
  end
37
38
 
38
- def create_models
39
- if model?
40
-
41
- models.each do |model|
42
- @model_name = model[:model_name]
43
- @model_klass_name = "#{namespace}_#{name}_Model_#{@model_name}"
44
- @model_name_lower = model[:model_name_lower]
45
-
46
- @resource_model_klass_name = "#{namespace}_#{name}_Model_Mysql4_#{@model_name}"
47
- @table_name = model[:model_table_name]
48
- template("Model.php", "#{model_path}#{@model_name}.php")
49
- template("Resource_Model.php", "#{resource_model_path}#{@model_name}.php")
50
- end
51
-
52
- @setup_path = "#{setup_base_path}#{name_lower}_setup/"
53
- empty_directory(@setup_path)
54
- template("mysql4-install.php", "#{@setup_path}mysql4-install-#{version}.php")
55
- end
56
- end
57
-
58
39
  private
59
40
 
60
- def namespace
61
- arguments[:namespace]
62
- end
63
-
64
- def name
65
- arguments[:name]
66
- end
67
-
68
- def combined_namespace
69
- "#{arguments[:namespace]}_#{arguments[:name]}"
70
- end
71
-
72
- def namespace_lower
73
- namespace.downcase
74
- end
75
-
76
- def name_lower
77
- name.downcase
78
- end
79
-
80
- #alias for name
81
- def extension_name_lower
82
- name.downcase
83
- end
84
-
85
- def author
86
- arguments[:author]
87
- end
88
-
89
- def version
90
- arguments[:version]
91
- end
92
-
93
- def global_config_basepath
94
- "app/etc/modules/"
95
- end
96
-
97
- def extension_base_path
98
- "app/code/local/#{namespace}/#{name}/"
99
- end
100
-
101
- def extension_config_path
102
- "#{extension_base_path}etc/"
103
- end
104
-
105
- def model_path
106
- "#{extension_base_path}Model/"
107
- end
108
-
109
- def resource_model_path
110
- "#{model_path}Mysql4/"
111
- end
112
-
113
- def helper_path
114
- "#{extension_base_path}Helper/"
115
- end
116
-
117
- def setup_base_path
118
- "#{extension_base_path}/sql/"
119
- end
120
-
121
- def model_klass_name
122
- "#{combined_namespace}_Model"
123
- end
124
-
125
- def resource_model_name_lower
126
- "#{name_lower}_mysql4"
127
- end
128
-
129
- def resource_model_klass_name
130
- "#{combined_namespace}_Model_Mysql4"
131
- end
132
-
133
- def observer?
134
- if arguments[:observer] == true
135
- return true
136
- else
137
- return false
138
- end
139
- end
140
-
141
- def observers
142
- arguments[:observer_events]
143
- end
144
-
145
- def helper?
146
- if arguments[:helper] == true
147
- return true
148
- else
149
- return false
150
- end
151
- end
152
-
153
- def model?
154
- if arguments[:model] == true
155
- return true
156
- else
157
- return false
158
- end
159
- end
160
-
161
- def models
162
- arguments[:models]
163
- end
41
+ # def namespace
42
+ # arguments[:namespace]
43
+ # end
44
+ #
45
+ # def name
46
+ # arguments[:name]
47
+ # end
48
+ #
49
+ # def combined_namespace
50
+ # "#{arguments[:namespace]}_#{arguments[:name]}"
51
+ # end
52
+ #
53
+ # def namespace_lower
54
+ # namespace.downcase
55
+ # end
56
+ #
57
+ # def name_lower
58
+ # name.downcase
59
+ # end
60
+ #
61
+ # #alias for name
62
+ # def extension_name_lower
63
+ # name.downcase
64
+ # end
65
+ #
66
+ # def author
67
+ # arguments[:author]
68
+ # end
69
+ #
70
+ # def version
71
+ # arguments[:version]
72
+ # end
73
+ #
74
+ # def global_config_basepath
75
+ # "app/etc/modules/"
76
+ # end
77
+ #
78
+ # def extension_base_path
79
+ # "app/code/local/#{namespace}/#{name}/"
80
+ # end
81
+ #
82
+ # def extension_config_path
83
+ # "#{extension_base_path}etc/"
84
+ # end
85
+ #
86
+ # def model_path
87
+ # "#{extension_base_path}Model/"
88
+ # end
89
+ #
90
+ # def resource_model_path
91
+ # "#{model_path}Mysql4/"
92
+ # end
93
+ #
94
+ # def helper_path
95
+ # "#{extension_base_path}Helper/"
96
+ # end
97
+ #
98
+ # def setup_base_path
99
+ # "#{extension_base_path}/sql/"
100
+ # end
101
+ #
102
+ # def model_klass_name
103
+ # "#{combined_namespace}_Model"
104
+ # end
105
+ #
106
+ # def resource_model_name_lower
107
+ # "#{name_lower}_mysql4"
108
+ # end
109
+ #
110
+ # def resource_model_klass_name
111
+ # "#{combined_namespace}_Model_Mysql4"
112
+ # end
113
+ #
114
+ # def observer?
115
+ # if arguments[:observer] == true
116
+ # return true
117
+ # else
118
+ # return false
119
+ # end
120
+ # end
121
+ #
122
+ # def observers
123
+ # arguments[:observer_events]
124
+ # end
125
+ #
126
+ # def helper?
127
+ # if arguments[:helper] == true
128
+ # return true
129
+ # else
130
+ # return false
131
+ # end
132
+ # end
133
+ #
134
+ # def model?
135
+ # if arguments[:model] == true
136
+ # return true
137
+ # else
138
+ # return false
139
+ # end
140
+ # end
141
+ #
142
+ # def models
143
+ # arguments[:models]
144
+ # end
164
145
 
165
146
  end
166
147
  end
@@ -6,14 +6,12 @@ $installer->startSetup();
6
6
 
7
7
  $installer->run("
8
8
  <% models.each do |model| %>
9
- -- DROP TABLE IF EXISTS {$this->getTable('<%= model[:model_table_name] %>')};
9
+ DROP TABLE IF EXISTS {$this->getTable('<%= model[:model_table_name] %>')};
10
10
  CREATE TABLE {$this->getTable('<%= model[:model_table_name] %>')} (
11
11
  `id` int(11) unsigned NOT NULL auto_increment,
12
- <%= model[:sql] %>
13
- PRIMARY KEY (`id`)
12
+ <%= model[:sql] %>
14
13
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
15
14
  <% end %>
16
-
17
- ");
15
+ ");
18
16
 
19
17
  $installer->endSetup();
@@ -4,5 +4,6 @@
4
4
  <% models.each do |model| %>
5
5
  <<%= model[:model_name_lower] %>><table><%= model[:model_table_name] %></table></<%= model[:model_name_lower] %>>
6
6
  <% end %>
7
+
7
8
  </entities>
8
9
  </<%= resource_model_name %>>
@@ -0,0 +1,5 @@
1
+ <% models.each do |model| %>
2
+ <<%= model[:model_name_lower] %>><table><%= model[:model_table_name] %></table></<%= model[:model_name_lower] %>>
3
+
4
+ <% end %>
5
+
@@ -3,7 +3,10 @@ require 'nokogiri'
3
3
  module Saruman
4
4
  module Generators
5
5
  class Model < Thor::Group
6
+
6
7
  include Thor::Actions
8
+ include Saruman::Base
9
+
7
10
  argument :arguments, :type => :hash
8
11
 
9
12
  def self.source_root
@@ -20,161 +23,65 @@ module Saruman
20
23
  end
21
24
  end
22
25
 
23
- def create_model_directory
24
- empty_directory(model_path) unless File.directory?(model_path)
26
+ def load_builders
27
+ @model_xml_config_builder = Saruman::ModelXmlConfigBuilder.new(models, self)
25
28
  end
26
29
 
27
- def create_temp_directory
28
- empty_directory("#{extension_temp_path}")
30
+ def create_model_directory
31
+ empty_directory(model_path) unless File.directory?(model_path)
29
32
  end
30
33
 
31
- def read_extension_config
32
-
33
- fp = "#{extension_config_path}/config.xml"
34
- config = File.open(fp, "r+")
35
-
36
- @config = Nokogiri::XML(config)
37
- config.close
34
+ def modify_config
38
35
 
39
- @extension_current_version = @config.css("version").first.content
36
+ @config = read_extension_config
40
37
 
41
- global_node = @config.css("global")
42
-
43
- models_node = global_node.css("models")
38
+ unless config_has_tag?("config global")
39
+ insert_tag_at_node("global", "config")
40
+ end
44
41
 
45
- if models_node.empty?
46
- models_node = Nokogiri::XML::Node.new('models', @config)
47
- global_node.first.add_child(models_node)
42
+ unless config_has_tag?("config global models")
43
+ insert_tag_at_node("models", "config global")
48
44
  end
49
45
 
50
- model_declaration_node = @config.css("models #{name_lower}")
46
+ unless config_has_tag?("models #{name_lower}")
47
+ insert_xml_at_node(@model_xml_config_builder.config_global_models_model_xml, "config models")
48
+ insert_xml_at_node(@model_xml_config_builder.config_models_resource_xml, "config models")
49
+ else
50
+ insert_xml_at_node(@model_xml_config_builder.config_models_resource_entities_xml, "#{name_lower}_mysql4 entities")
51
+ end
51
52
 
52
- if model_declaration_node.empty?
53
- @resource_model_config_temp_path = "#{extension_temp_path}_config.xml"
54
- template("resource_model_config_block.xml", @resource_model_config_temp_path)
55
- resource_model_config_file = File.open(@resource_model_config_temp_path)
56
- resource_model_config_block = Nokogiri::XML(resource_model_config_file).root
57
- resource_model_config_file.close
58
-
59
- @model_config_temp_path = "#{extension_temp_path}model_config_block.xml"
60
- template("model_config_block.xml", @model_config_temp_path)
61
- model_config_file = File.open(@model_config_temp_path)
62
- model_config_block = Nokogiri::XML(model_config_file).root
63
- model_config_file.close
64
-
65
- models_node = @config.css("models").first
66
-
67
- models_node.add_child(model_config_block)
68
- models_node.add_child(resource_model_config_block)
69
-
53
+ unless config_has_tag?("resources")
54
+ insert_xml_at_node(@model_xml_config_builder.config_global_resources_xml, "config global resources")
70
55
  end
71
-
72
- models_node_find = @config.css('models')
73
-
74
- file = File.open(fp,'w')
75
- file.puts @config.to_xml
76
- file.close
77
-
56
+
57
+ write_extension_config
58
+
78
59
  end
79
60
 
80
- def remove_temp_dir
81
- FileUtils.rm_rf(extension_temp_path)
61
+ def create_models
62
+ models.each do |model|
63
+ @model_name = model[:model_name]
64
+ @model_klass_name = "#{namespace}_#{name}_Model_#{@model_name}"
65
+ @model_name_lower = model[:model_name_lower]
66
+
67
+ @resource_model_klass_name = "#{namespace}_#{name}_Model_Mysql4_#{@model_name}"
68
+ @table_name = model[:model_table_name]
69
+ template("Model.php", "#{model_path}#{@model_name}.php")
70
+ template("Resource_Model.php", "#{resource_model_path}#{@model_name}.php")
71
+ end
82
72
  end
83
73
 
84
74
  def create_installer_upgrade
85
- template("mysql4-install.php", "#{setup_base_path}/mysql4-upgrade-#{@extension_current_version}-#{extension_upgrade_version}.php")
86
- end
87
-
88
- private
89
-
90
- def namespace
91
- arguments[:namespace]
92
- end
93
-
94
- def name
95
- arguments[:name]
96
- end
97
-
98
- def combined_namespace
99
- "#{arguments[:namespace]}_#{arguments[:name]}"
100
- end
101
-
102
- def namespace_lower
103
- namespace.downcase
104
- end
105
-
106
- def name_lower
107
- name.downcase
108
- end
109
-
110
- #alias for name
111
- def extension_name_lower
112
- name.downcase
113
- end
114
-
115
- def version
116
- arguments[:version]
117
- end
118
-
119
- def global_config_basepath
120
- "app/etc/modules/"
121
- end
122
-
123
- def extension_base_path
124
- "app/code/local/#{namespace}/#{name}/"
125
- end
126
-
127
- def extension_temp_path
128
- "#{extension_base_path}temp/"
129
- end
130
-
131
- def extension_config_path
132
- "#{extension_base_path}etc/"
133
- end
134
-
135
- def model_path
136
- "#{extension_base_path}Model/"
137
- end
138
-
139
- def resource_model_path
140
- "#{model_path}Mysql4/"
141
- end
142
-
143
- def setup_base_path
144
- "#{extension_base_path}sql/#{name_lower}_setup/"
145
- end
146
-
147
- def model_klass_name
148
- "#{combined_namespace}_Model"
149
- end
150
-
151
- def resource_model_name
152
- "#{extension_name_lower}_mysql4"
153
- end
154
-
155
- def resource_model_klass_name
156
- "#{combined_namespace}_Model_Mysql4"
157
- end
158
-
159
- def global_config_file_path
160
- "#{global_config_basepath}#{combined_namespace}.xml"
161
- end
162
-
163
- def extension_upgrade_version
164
- @extension_current_version.to_f + 0.1
165
- end
166
-
167
- def model?
168
- if arguments[:model] == true
169
- return true
75
+ if command.to_s == "extension"
76
+ template("mysql4-install.php", "#{setup_base_path}/mysql4-install-#{version}.php")
77
+ elsif command.to_s == "model"
78
+ template("mysql4-install.php", "#{setup_base_path}/mysql4-upgrade-#{extension_current_version}-#{extension_upgrade_version}.php")
170
79
  else
171
- return false
80
+
172
81
  end
173
82
  end
174
83
 
175
- def models
176
- arguments[:models]
177
- end
84
+ private
178
85
 
179
86
  end
180
87
  end
@@ -87,7 +87,6 @@ app/code/core/Mage/Catalog/Model/Product/Action.php,123,catalog_product_website_
87
87
  app/code/core/Mage/Catalog/Model/Product/Attribute/Source/Inputtype.php,55,adminhtml_product_attribute_types
88
88
  app/code/core/Mage/Catalog/Model/Product/Option/Api.php,166,catalog_product_prepare_save
89
89
  app/code/core/Mage/Catalog/Model/Product/Status.php,217,catalog_product_status_update
90
- app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php,542,"Mage::dispatchEvent($eventName, array("
91
90
  app/code/core/Mage/Catalog/Model/Product/Type/Configurable/Price.php,71,catalog_product_type_configurable_price
92
91
  app/code/core/Mage/Catalog/Model/Product/Type/Grouped/Price.php,70,catalog_product_type_grouped_price
93
92
  app/code/core/Mage/Catalog/Model/Product/Type/Price.php,68,catalog_product_get_final_price
@@ -0,0 +1,13 @@
1
+ <?php
2
+
3
+ class <%= combined_namespace %>_Model_Observer
4
+ {
5
+ <% observers.each do |event| %>
6
+ public function <%= event %>($observer)
7
+ {
8
+ $event = $observer->getEvent();
9
+ Mage::log("I put on my robe and wizard hat");
10
+ Mage::log($event->getEventName().' was called. Winning!');
11
+ }
12
+ <% end %>
13
+ }
@@ -0,0 +1,47 @@
1
+ require 'thor/group'
2
+ require 'nokogiri'
3
+ module Saruman
4
+ module Generators
5
+ class Observer < Thor::Group
6
+
7
+ include Thor::Actions
8
+ include Saruman::Base
9
+
10
+ argument :arguments, :type => :hash
11
+
12
+ def self.source_root
13
+ File.dirname(__FILE__) + "/observer/templates"
14
+ end
15
+
16
+ def load_builders
17
+ @observer_xml_config_builder = Saruman::ObserverXmlConfigBuilder.new(observers, self)
18
+ end
19
+
20
+ def modify_config
21
+
22
+ @config = read_extension_config
23
+
24
+ unless config_has_tag?("config frontend")
25
+ insert_tag_at_node("frontend", "config")
26
+ end
27
+
28
+ unless config_has_tag?("config frontend events")
29
+ insert_tag_at_node("events", "config frontend")
30
+ end
31
+
32
+ insert_xml_at_node(@observer_xml_config_builder.config_frontend_events_observers_xml, "config frontend events")
33
+
34
+ write_extension_config
35
+
36
+ end
37
+
38
+ def create_observers
39
+ template("Observer.php", "#{model_path}Observer.php")
40
+ end
41
+
42
+ private
43
+
44
+ end
45
+
46
+ end
47
+ end
@@ -2,4 +2,5 @@ require 'thor/group'
2
2
 
3
3
  require "saruman/generators/extension"
4
4
  require "saruman/generators/model"
5
+ require "saruman/generators/observer"
5
6
  require "saruman"
@@ -1,3 +1,3 @@
1
1
  module Saruman
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/saruman.rb CHANGED
@@ -1,7 +1,235 @@
1
1
  require "saruman/version"
2
2
  require "highline"
3
+ require "virtus"
4
+ require "saruman"
5
+ require "nokogiri"
6
+ require 'active_support'
3
7
  module Saruman
4
8
 
9
+ module Base
10
+
11
+ def namespace
12
+ arguments[:namespace]
13
+ end
14
+
15
+ def name
16
+ arguments[:name]
17
+ end
18
+
19
+ def combined_namespace
20
+ "#{arguments[:namespace]}_#{arguments[:name]}"
21
+ end
22
+
23
+ def namespace_lower
24
+ namespace.downcase
25
+ end
26
+
27
+ def name_lower
28
+ name.downcase
29
+ end
30
+
31
+ #alias for name
32
+ def extension_name_lower
33
+ name.downcase
34
+ end
35
+
36
+ def global_config_basepath
37
+ "#{Dir.pwd}/app/etc/modules/"
38
+ end
39
+
40
+ def extension_base_path
41
+ "#{Dir.pwd}/app/code/local/#{namespace}/#{name}/"
42
+ end
43
+
44
+ def extension_temp_path
45
+ "#{extension_base_path}temp/"
46
+ end
47
+
48
+ def extension_config_path
49
+ "#{extension_base_path}etc/"
50
+ end
51
+
52
+ def model_path
53
+ "#{extension_base_path}Model/"
54
+ end
55
+
56
+ def helper_path
57
+ "#{extension_base_path}Helper/"
58
+ end
59
+
60
+ def resource_model_path
61
+ "#{model_path}Mysql4/"
62
+ end
63
+
64
+ def setup_base_path
65
+ "#{extension_base_path}sql/#{name_lower}_setup/"
66
+ end
67
+
68
+ def model_klass_name
69
+ "#{combined_namespace}_Model"
70
+ end
71
+
72
+ def resource_model_name
73
+ "#{extension_name_lower}_mysql4"
74
+ end
75
+
76
+ def resource_model_klass_name
77
+ "#{combined_namespace}_Model_Mysql4"
78
+ end
79
+
80
+ def global_config_file_path
81
+ "#{global_config_basepath}#{combined_namespace}.xml"
82
+ end
83
+
84
+ def model?
85
+ if arguments[:model] == true
86
+ return true
87
+ else
88
+ return false
89
+ end
90
+ end
91
+
92
+ def models
93
+ arguments[:models]
94
+ end
95
+
96
+ def command
97
+ arguments[:command]
98
+ end
99
+
100
+ def version
101
+ arguments[:version]
102
+ end
103
+
104
+ def author
105
+ arguments[:author]
106
+ end
107
+
108
+ def observer?
109
+ if arguments[:observer] == true
110
+ return true
111
+ else
112
+ return false
113
+ end
114
+ end
115
+
116
+ def observers
117
+ arguments[:observer_events]
118
+ end
119
+
120
+ def helper?
121
+ if arguments[:helper] == true
122
+ return true
123
+ else
124
+ return false
125
+ end
126
+ end
127
+
128
+ def extension_config_file_path
129
+ "#{extension_config_path}config.xml"
130
+ end
131
+
132
+ def read_extension_config
133
+ config = File.open(extension_config_file_path, "r+")
134
+ @config = Nokogiri::XML(config)
135
+ config.close
136
+ @config
137
+ end
138
+
139
+ def write_extension_config
140
+ file = File.open(extension_config_file_path,'w')
141
+ file.puts @config.to_xml
142
+ file.close
143
+ end
144
+
145
+ def extension_current_version
146
+ @extension_current_version = @config.css("version").first.content
147
+ end
148
+
149
+ def extension_upgrade_version
150
+ digits = extension_current_version.to_s.split(".")
151
+ current_version_float = "#{digits[0]}.#{digits[1]}#{digits[2]}".to_f
152
+ @extension_upgrade_version = (current_version_float + 0.01).to_s.sub(".", "").chars.to_a.join(".")
153
+ end
154
+
155
+ def config_has_tag?(tag_lookup)
156
+ target = @config.css(tag_lookup).first
157
+ if target.nil?
158
+ return false
159
+ else
160
+ return true
161
+ end
162
+ end
163
+
164
+ def insert_tag_at_node(tag, tag_lookup)
165
+ target_tag = @config.css(tag_lookup).first
166
+ puts "inserting #{tag} from looku #{tag_lookup}"
167
+ unless target_tag.nil?
168
+ new_tag = "<#{tag}></#{tag}>"
169
+ target_tag.add_child(new_tag)
170
+ end
171
+ end
172
+
173
+ def insert_xml_at_node(xml, tag_lookup)
174
+ target_tag = @config.css(tag_lookup).first
175
+ unless target_tag.nil?
176
+ target_tag.add_child(xml)
177
+ end
178
+ end
179
+
180
+ end
181
+
182
+
183
+ module MenuBuilder
184
+ include Virtus
185
+ attribute :decisions, Array, :default => []
186
+
187
+ # def decisions
188
+ # return decisions_made
189
+ # end
190
+
191
+ end
192
+
193
+ class ObserverMenuBuilder
194
+
195
+ # include Virtus
196
+ include MenuBuilder
197
+ # attribute :chosen_events, Array
198
+ attribute :observer_events, Array, :default => []
199
+ # attribute :decisions, Array, :default => []
200
+ BASE_DIR = File.dirname(__FILE__)
201
+ OBSERVER_EVENTS_FILE_PATH = BASE_DIR+"/saruman/generators/observer/observer_events.csv"
202
+
203
+ def initialize(menu)
204
+ @events_file = File.open(OBSERVER_EVENTS_FILE_PATH, 'r')
205
+ @observer_events = []
206
+ @events_file.readlines.each do |row|
207
+ cells = row.strip().split(",")
208
+ @observer_events.push({:event_name => cells[2], :file => cells[0], :line => cells[1]})
209
+ end
210
+ @events_file.close
211
+ display_choices(menu)
212
+ end
213
+
214
+ #make the choices pretty, longest string length minus offset, and take into account number of base digits of the choice
215
+ def pad_command_line(string, offset, index)
216
+ padding = ""
217
+ l = ((offset - string.length) - index.to_s.length)
218
+ l.times do
219
+ padding << " "
220
+ end
221
+ padding
222
+ end
223
+
224
+ def display_choices(menu)
225
+ observer_events.each_with_index do |event,index|
226
+ menu.choice("#{event[:event_name]} #{pad_command_line(event[:event_name],67,index+1)} File: #{event[:file]} #{pad_command_line(event[:file],96,index+1)} Line: #{event[:line]}") { decisions.push(event[:event_name])}
227
+ end
228
+ menu
229
+ end
230
+
231
+ end
232
+
5
233
  class ModelBuilder
6
234
  def initialize
7
235
  ask_question
@@ -11,7 +239,7 @@ module Saruman
11
239
  model_name = ask("Enter Name of model") { |q| q.default = "Post" }
12
240
  model_table_name = ask("Enter Table Name of model") { |q| q.default = "blog_post" }
13
241
  model_fields_input = ask("Enter Model Fields") { |q| q.default = "title:string active:boolean blog_id:integer:index" }
14
- model_sql = parse_model_fields(model_fields_input)
242
+ model_sql = parse_model_fields(model_fields_input, model_table_name)
15
243
  @question_answer = {:model_name => model_name, :model_name_lower => model_name.downcase, :model_table_name => model_table_name, :sql => model_sql}
16
244
  @question_answer
17
245
  end
@@ -20,12 +248,16 @@ module Saruman
20
248
  return @question_answer
21
249
  end
22
250
 
23
- def parse_model_fields(model_fields)
251
+ def parse_model_fields(model_fields, model_table_name)
24
252
  sql = ""
253
+ index_sql = ""
25
254
  model_fields.split(" ").each do |field|
26
- field = Saruman::ModelBuilderField.new(field)
255
+ field = Saruman::ModelBuilderField.new(field, model_table_name)
27
256
  sql << field.sql + ",\n"
257
+ index_sql << field.index_sql if field.index?
28
258
  end
259
+ sql << index_sql
260
+ sql << " PRIMARY KEY (`id`) \n"
29
261
  sql
30
262
  end
31
263
 
@@ -33,11 +265,12 @@ module Saruman
33
265
 
34
266
  class ModelBuilderField
35
267
 
36
- SQL_TYPE_MAPPINGS = {:string => "varchar(255)", :text => "text NOT NULL", :boolean => "tinyint(1) NOT NULL default 0", :date => "DATETIME default NULL", :int => "int(10)" }
37
- attr_accessor :sql, :sql_type, :index
268
+ SQL_TYPE_MAPPINGS = {:string => "varchar(255)", :text => "text NOT NULL", :boolean => "tinyint(1) NOT NULL default 0", :date => "DATETIME default NULL", :int => "int(10)", :integer => "int(10)" }
269
+ attr_accessor :sql, :sql_type, :index, :segs, :index_sql
270
+ SQL_LINE_PADDING = " "
38
271
 
39
- def initialize(field)
40
- segs = field.split(":")
272
+ def initialize(field, model_table_name)
273
+ @segs = field.split(":")
41
274
 
42
275
  case segs.length
43
276
  when 1
@@ -48,11 +281,139 @@ module Saruman
48
281
  @sql_type = segs[1].to_sym
49
282
  end
50
283
 
51
- @sql = "`#{segs[0]}` #{SQL_TYPE_MAPPINGS[sql_type]}"
52
- @index = true if(segs.length == 3)
53
-
284
+ @sql = "#{SQL_LINE_PADDING}`#{segs[0]}` #{SQL_TYPE_MAPPINGS[sql_type]}"
285
+ if index?
286
+ @index = true
287
+ @index_sql = "#{SQL_LINE_PADDING}KEY `IDX_#{model_table_name.upcase}_#{segs[0].upcase}` (`#{segs[0]}`),\n"
288
+ end
289
+ end
290
+
291
+ def index?
292
+ if(@segs.length==3)
293
+ return true
294
+ else
295
+ return false
296
+ end
297
+ end
298
+
299
+ end
300
+
301
+ module XmlBuilderBase
302
+ def method_missing(meth, *args, &block)
303
+ if(@generator.respond_to?(meth.to_sym, true))
304
+ @generator.send(meth.to_sym, *args)
305
+ else
306
+ super
307
+ end
308
+ end
309
+ end
310
+
311
+ class ModelXmlConfigBuilder
312
+ include Virtus
313
+ include XmlBuilderBase
314
+ attribute :models, Array
315
+ attribute :config_models_resource_entities_xml, String
316
+ attribute :config_models_resource_xml, String
317
+ attribute :config_global_models_model_xml, String
318
+ attribute :config_global_resources_xml, String
319
+
320
+ def initialize(models, generator)
321
+ @models = models
322
+ @generator = generator
323
+ @config_models_resource_entities_xml = set_config_models_resource_entities_xml
324
+ @config_models_resource_xml = set_config_models_resource_xml
325
+ @config_global_models_model_xml = set_config_global_models_model_xml
326
+ @config_global_resources_xml = set_config_global_resources_xml
327
+ end
328
+
329
+ def set_config_models_resource_entities_xml
330
+ xml = ""
331
+ models.each do |model|
332
+ xml << "<#{model[:model_name_lower]}><table>#{model[:model_table_name]}</table></#{model[:model_name_lower]}>\n"
333
+ end
334
+ return xml
335
+ end
336
+
337
+ def set_config_models_resource_xml
338
+ xml = "
339
+ <#{resource_model_name}>
340
+ <class>#{resource_model_klass_name}</class>
341
+ <entities>
342
+ #{config_models_resource_entities_xml}
343
+ </entities>
344
+ </#{resource_model_name}>
345
+ "
346
+ return xml
347
+ end
348
+
349
+ def set_config_global_models_model_xml
350
+ xml = "
351
+ <#{extension_name_lower}>
352
+ <class>#{model_klass_name}</class>
353
+ <resourceModel>#{resource_model_name}</resourceModel>
354
+ </#{extension_name_lower}>
355
+ "
356
+ return xml
357
+ end
358
+
359
+ def set_config_global_resources_xml
360
+ xml = "
361
+ <resources>
362
+ <#{extension_name_lower}_setup>
363
+ <setup>
364
+ <module>#{combined_namespace}</module>
365
+ </setup>
366
+ <connection>
367
+ <use>core_setup</use>
368
+ </connection>
369
+ </#{extension_name_lower}_setup>
370
+ <#{extension_name_lower}_write>
371
+ <connection>
372
+ <use>core_write</use>
373
+ </connection>
374
+ </#{extension_name_lower}_write>
375
+ <#{extension_name_lower}_read>
376
+ <connection>
377
+ <use>core_read</use>
378
+ </connection>
379
+ </#{extension_name_lower}_read>
380
+ </resources>
381
+ "
382
+ return xml
54
383
  end
55
384
 
56
385
  end
57
386
 
387
+ class ObserverXmlConfigBuilder
388
+ include Virtus
389
+ include XmlBuilderBase
390
+ attribute :observers, Array
391
+ attribute :config_frontend_events_observers_xml, String
392
+
393
+ def initialize(observers, generator)
394
+ @observers = observers
395
+ @generator = generator
396
+ @config_frontend_events_observers_xml = set_config_frontend_events_observers_xml
397
+ end
398
+
399
+ def set_config_frontend_events_observers_xml
400
+ xml=""
401
+ observers.each do |event|
402
+ xml << "
403
+ <#{event}>
404
+ <observers>
405
+ <#{combined_namespace}_Model_Observer>
406
+ <type>singleton</type>
407
+ <class>#{combined_namespace}_Model_Observer</class>
408
+ <method>#{event}</method>
409
+ </#{combined_namespace}_Model_Observer>
410
+ </observers>
411
+ </#{event}>
412
+ "
413
+ end
414
+ return xml
415
+ end
416
+
417
+ end
418
+
58
419
  end
data/saruman.gemspec CHANGED
@@ -26,7 +26,8 @@ Gem::Specification.new do |s|
26
26
  s.add_dependency "thor"
27
27
  s.add_dependency "highline"
28
28
  s.add_dependency "nokogiri"
29
- s.add_dependency "roxml"
29
+ s.add_dependency "virtus"
30
+
30
31
  s.add_development_dependency "rspec", "~> 2.6"
31
32
  s.add_development_dependency "cucumber"
32
33
  s.add_development_dependency "aruba"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saruman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-11 00:00:00.000000000 Z
12
+ date: 2012-06-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -76,7 +76,7 @@ dependencies:
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
- name: roxml
79
+ name: virtus
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
@@ -158,19 +158,19 @@ files:
158
158
  - lib/saruman/cli.rb
159
159
  - lib/saruman/generators/extension.rb
160
160
  - lib/saruman/generators/extension/templates/Helper.php
161
- - lib/saruman/generators/extension/templates/Model.php
162
161
  - lib/saruman/generators/extension/templates/Observer.php
163
- - lib/saruman/generators/extension/templates/Resource_Model.php
164
162
  - lib/saruman/generators/extension/templates/extension_config.xml
165
163
  - lib/saruman/generators/extension/templates/module.xml
166
- - lib/saruman/generators/extension/templates/mysql4-install.php
167
164
  - lib/saruman/generators/model.rb
168
165
  - lib/saruman/generators/model/templates/Model.php
169
166
  - lib/saruman/generators/model/templates/Resource_Model.php
170
167
  - lib/saruman/generators/model/templates/model_config_block.xml
171
168
  - lib/saruman/generators/model/templates/mysql4-install.php
172
169
  - lib/saruman/generators/model/templates/resource_model_config_block.xml
170
+ - lib/saruman/generators/model/templates/resource_model_entities_models_block.xml
171
+ - lib/saruman/generators/observer.rb
173
172
  - lib/saruman/generators/observer/observer_events.csv
173
+ - lib/saruman/generators/observer/templates/Observer.php
174
174
  - lib/saruman/generators/saruman.rb
175
175
  - lib/saruman/version.rb
176
176
  - saruman.gemspec
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- class <%= @model_klass_name %> extends Mage_Core_Model_Abstract
4
- {
5
- public function _construct()
6
- {
7
- parent::_construct();
8
- $this->_init('<%= name_lower %>/<%= @model_name_lower %>');
9
- }
10
-
11
- }
@@ -1,10 +0,0 @@
1
- <?php
2
-
3
- class <%= @resource_model_klass_name %> extends Mage_Core_Model_Mysql4_Abstract
4
- {
5
- public function _construct()
6
- {
7
- $this->_init('<%= name.downcase %>/<%= @model_name.downcase %>', '<%= @table_name %>_id');
8
- }
9
-
10
- }
@@ -1,19 +0,0 @@
1
- <?php
2
-
3
- $installer = $this;
4
-
5
- $installer->startSetup();
6
-
7
- $installer->run("
8
- <% models.each do |model| %>
9
- -- DROP TABLE IF EXISTS {$this->getTable('<%= model[:model_table_name] %>')};
10
- CREATE TABLE {$this->getTable('<%= model[:model_table_name] %>')} (
11
- `id` int(11) unsigned NOT NULL auto_increment,
12
- <%= model[:sql] %>
13
- PRIMARY KEY (`id`)
14
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
15
- <% end %>
16
-
17
- ");
18
-
19
- $installer->endSetup();