Responsive Menu - Version 3.1.16

Version Description

(15th August 2018) = * Added ability to upload and use themes.

Download this release

Release Info

Developer peterfeatherstone
Plugin Icon 128x128 Responsive Menu
Version 3.1.16
Comparing to
See all releases

Code changes from version 3.1.15 to 3.1.16

app/Collections/OptionsCollection.php CHANGED
@@ -19,7 +19,7 @@ class OptionsCollection implements \ArrayAccess, \Countable {
19
 
20
  public function getActiveArrow() {
21
  if($this->options['active_arrow_image'])
22
- return '<img alt="' . $this->options['active_arrow_image_alt'] .'" src="' . $this->options['active_arrow_image'] .'" />';
23
 
24
  return $this->options['active_arrow_shape'];
25
 
@@ -27,7 +27,7 @@ class OptionsCollection implements \ArrayAccess, \Countable {
27
 
28
  public function getInActiveArrow() {
29
  if($this->options['inactive_arrow_image'])
30
- return '<img alt="' . $this->options['inactive_arrow_image_alt'] .'" src="' . $this->options['inactive_arrow_image'] .'" />';
31
 
32
  return $this->options['inactive_arrow_shape'];
33
 
@@ -35,7 +35,7 @@ class OptionsCollection implements \ArrayAccess, \Countable {
35
 
36
  public function getTitleImage() {
37
  if($this->options['menu_title_image'])
38
- return '<img alt="' . $this->options['menu_title_image_alt'] .'" src="' . $this->options['menu_title_image'] .'" />';
39
 
40
  return null;
41
 
@@ -43,14 +43,14 @@ class OptionsCollection implements \ArrayAccess, \Countable {
43
 
44
  public function getButtonIcon() {
45
  if($this->options['button_image'])
46
- return '<img alt="' . $this->options['button_image_alt'] .'" src="' . $this->options['button_image'] .'" class="responsive-menu-button-icon responsive-menu-button-icon-active" />';
47
 
48
  return '<span class="responsive-menu-inner"></span>';
49
  }
50
 
51
  public function getButtonIconActive() {
52
  if($this->options['button_image'])
53
- return '<img alt="' . $this->options['button_image_alt_when_clicked'] .'" src="' . $this->options['button_image_when_clicked'] .'" class="responsive-menu-button-icon responsive-menu-button-icon-inactive" />';
54
  }
55
 
56
  public function offsetExists($offset) {
@@ -83,4 +83,13 @@ class OptionsCollection implements \ArrayAccess, \Countable {
83
  return count($this->options);
84
  }
85
 
 
 
 
 
 
 
 
 
 
86
  }
19
 
20
  public function getActiveArrow() {
21
  if($this->options['active_arrow_image'])
22
+ return '<img alt="' . $this->options['active_arrow_image_alt'] .'" src="' . $this->getThemedUrl($this->options['active_arrow_image']) .'" />';
23
 
24
  return $this->options['active_arrow_shape'];
25
 
27
 
28
  public function getInActiveArrow() {
29
  if($this->options['inactive_arrow_image'])
30
+ return '<img alt="' . $this->options['inactive_arrow_image_alt'] .'" src="' . $this->getThemedUrl($this->options['inactive_arrow_image']) .'" />';
31
 
32
  return $this->options['inactive_arrow_shape'];
33
 
35
 
36
  public function getTitleImage() {
37
  if($this->options['menu_title_image'])
38
+ return '<img alt="' . $this->options['menu_title_image_alt'] .'" src="' . $this->getThemedUrl($this->options['menu_title_image']) .'" />';
39
 
40
  return null;
41
 
43
 
44
  public function getButtonIcon() {
45
  if($this->options['button_image'])
46
+ return '<img alt="' . $this->options['button_image_alt'] .'" src="' . $this->getThemedUrl($this->options['button_image']) .'" class="responsive-menu-button-icon responsive-menu-button-icon-active" />';
47
 
48
  return '<span class="responsive-menu-inner"></span>';
49
  }
50
 
51
  public function getButtonIconActive() {
52
  if($this->options['button_image'])
53
+ return '<img alt="' . $this->options['button_image_alt_when_clicked'] .'" src="' . $this->getThemedUrl($this->options['button_image_when_clicked']) .'" class="responsive-menu-button-icon responsive-menu-button-icon-inactive" />';
54
  }
55
 
56
  public function offsetExists($offset) {
83
  return count($this->options);
84
  }
85
 
86
+ private function getThemedUrl($image_url) {
87
+ if($this->options['menu_theme']):
88
+ $theme_url = wp_upload_dir()['baseurl'] . '/responsive-menu-themes/' . $this->options['menu_theme'];
89
+ $image_url = str_replace('{theme_images}', $theme_url . '/images', $image_url);
90
+ endif;
91
+
92
+ return $image_url;
93
+ }
94
+
95
  }
app/Controllers/AdminController.php CHANGED
@@ -7,55 +7,204 @@ use ResponsiveMenu\Validation\Validator;
7
  use ResponsiveMenu\Tasks\UpdateOptionsTask;
8
  use ResponsiveMenu\Collections\OptionsCollection;
9
 
 
 
 
 
 
 
 
 
 
 
10
  class AdminController {
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  public function __construct(OptionManager $manager, View $view) {
13
  $this->manager = $manager;
14
  $this->view = $view;
15
  }
16
 
17
- public function index($nav_menus, $location_menus) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  return $this->view->render(
19
  'admin/main.html.twig',
20
  [
21
  'options' => $this->manager->all(),
22
- 'nav_menus' => $nav_menus,
23
- 'location_menus' => $location_menus
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  ]
25
  );
26
  }
27
 
28
- public function rebuild($nav_menus, $location_menus) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  return $this->view->render(
30
  'admin/main.html.twig',
31
  [
32
  'options' => $this->manager->all(),
33
- 'nav_menus' => $nav_menus,
34
- 'location_menus' => $location_menus,
35
- 'alert' => ['success' => 'Responsive Menu Database Rebuilt Successfully.']
36
  ]
37
  );
38
  }
39
 
40
- public function update($valid_nonce, $new_options, $nav_menus, $location_menus) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  $validator = new Validator();
42
  $errors = [];
 
43
  if(!$valid_nonce):
44
  $alert = ['danger' => 'CSRF token not valid'];
45
  $options = new OptionsCollection($new_options);
 
46
  elseif($validator->validate($new_options)):
47
  try {
48
  $options = $this->manager->updateOptions($new_options);
49
  $task = new UpdateOptionsTask;
50
  $task->run($options, $this->view);
51
  $alert = ['success' => 'Responsive Menu Options Updated Successfully.'];
 
52
  } catch (\Exception $e) {
53
  $alert = ['danger' => $e->getMessage()];
54
  }
 
55
  else:
56
  $options = new OptionsCollection($new_options);
57
  $errors = $validator->getErrors();
58
  $alert = ['danger' => $errors];
 
59
  endif;
60
 
61
  return $this->view->render(
@@ -63,36 +212,64 @@ class AdminController {
63
  [
64
  'options' => $options,
65
  'alert' => $alert,
66
- 'nav_menus' => $nav_menus,
67
- 'location_menus' => $location_menus,
68
  'errors' => $errors
69
  ]
70
  );
71
  }
72
 
73
- public function reset($default_options, $nav_menus, $location_menus) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  try {
75
  $options = $this->manager->updateOptions($default_options);
76
  $task = new UpdateOptionsTask;
77
  $task->run($options, $this->view);
78
  $alert = ['success' => 'Responsive Menu Options Reset Successfully'];
 
79
  } catch(\Exception $e) {
80
  $alert = ['danger' => $e->getMessage()];
81
  }
 
82
  return $this->view->render(
83
  'admin/main.html.twig',
84
  [
85
  'options' => $options,
86
- 'alert' => $alert,
87
- 'nav_menus' => $nav_menus,
88
- 'location_menus' => $location_menus
89
  ]
90
  );
91
  }
92
 
93
- public function import($imported_options, $nav_menus, $location_menus) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  $errors = [];
95
  if(!empty($imported_options)):
 
96
  $validator = new Validator();
97
  if($validator->validate($imported_options)):
98
  try {
@@ -105,14 +282,18 @@ class AdminController {
105
  $options = $this->manager->all();
106
  $alert = ['danger' => $e->getMessage()];
107
  }
 
108
  else:
109
  $options = new OptionsCollection($imported_options);
110
  $errors = $validator->getErrors();
111
  $alert = ['danger' => $errors];
 
112
  endif;
 
113
  else:
114
  $options = $this->manager->all();
115
  $alert = ['danger' => 'No import file selected'];
 
116
  endif;
117
 
118
  return $this->view->render(
@@ -120,13 +301,24 @@ class AdminController {
120
  [
121
  'options' => $options,
122
  'alert' => $alert,
123
- 'nav_menus' => $nav_menus,
124
- 'location_menus' => $location_menus,
125
  'errors' => $errors
126
  ]
127
  );
128
  }
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  public function export() {
131
  return json_encode(
132
  $this->manager->all()->toArray()
7
  use ResponsiveMenu\Tasks\UpdateOptionsTask;
8
  use ResponsiveMenu\Collections\OptionsCollection;
9
 
10
+ /**
11
+ * Entry point for all admin functionality.
12
+ *
13
+ * All routing for the admin comes through the functions below. When any
14
+ * button is pressed in the admin view, it will come through here.
15
+ *
16
+ * @author Peter Featherstone <peter@featherstone.me>
17
+ *
18
+ * @since 3.0
19
+ */
20
  class AdminController {
21
 
22
+ /**
23
+ * Constructor for setting up the AdminController.
24
+ *
25
+ * The constructor allows us to switch implementations for managing options
26
+ * and for rendering views. Useful for switching out mocked or stubbed
27
+ * classes during testing.
28
+ *
29
+ * @author Peter Featherstone <peter@featherstone.me>
30
+ *
31
+ * @since 3.0
32
+ *
33
+ * @param OptionManager $manager Instance of a Management options class.
34
+ * @param View $view Instance of a View class for rendering.
35
+ */
36
  public function __construct(OptionManager $manager, View $view) {
37
  $this->manager = $manager;
38
  $this->view = $view;
39
  }
40
 
41
+ /**
42
+ * Main GET route for the admin section.
43
+ *
44
+ * This is the default view for the plugin on an initial GET request to the
45
+ * page.
46
+ *
47
+ * @author Peter Featherstone <peter@featherstone.me>
48
+ *
49
+ * @since 3.0
50
+ *
51
+ * @return string Output HTML from rendered view.
52
+ */
53
+ public function index() {
54
+ return $this->view->render(
55
+ 'admin/main.html.twig', ['options' => $this->manager->all()]
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Rebuild database POST route for the admin section.
61
+ *
62
+ * This route is called when the Rebuild Database button is clicked from
63
+ * inside the admin section. The intention is to set the version back to
64
+ * a pre 3.0 version, which will then force a rebuild.
65
+ *
66
+ * @author Peter Featherstone <peter@featherstone.me>
67
+ *
68
+ * @since 3.0
69
+ *
70
+ * @return string Output HTML from rendered view.
71
+ */
72
+ public function rebuild() {
73
+ update_option('responsive_menu_version', '2.8.9');
74
+
75
  return $this->view->render(
76
  'admin/main.html.twig',
77
  [
78
  'options' => $this->manager->all(),
79
+ 'alert' => ['success' => 'Responsive Menu Database Rebuilt Successfully.']
80
+ ]
81
+ );
82
+ }
83
+
84
+
85
+ /**
86
+ * Apply a specific theme options and commit to the database.
87
+ *
88
+ * This route is called when the Apply Theme button is pressed inside the
89
+ * admin area. It loads in the options file for the theme and updates the
90
+ * options accordingly.
91
+ *
92
+ * @author Peter Featherstone <peter@featherstone.me>
93
+ *
94
+ * @since 3.1.16
95
+ *
96
+ * @param string $theme The theme name to apply
97
+ *
98
+ * @return string Output HTML from rendered view.
99
+ */
100
+ public function apply_theme($theme) {
101
+ $options = $this->manager->all();
102
+
103
+ $upload_folder = wp_upload_dir()['basedir'];
104
+ $theme_folder = $upload_folder . '/responsive-menu-themes/';
105
+ $options_file_location = $theme_folder . $theme . '/options.json';
106
+
107
+ $theme_options_file = file_get_contents($options_file_location);
108
+ $theme_options = json_decode($theme_options_file, true);
109
+
110
+ foreach($theme_options as $key => $value)
111
+ $options[$key] = $value;
112
+
113
+ $options['menu_theme'] = $theme;
114
+
115
+ $this->manager->updateOptions($options->toArray());
116
+
117
+ return $this->view->render(
118
+ 'admin/main.html.twig',
119
+ [
120
+ 'options' => $options,
121
+ 'alert' => ['success' => 'Responsive Menu Theme Applied Successfully.']
122
  ]
123
  );
124
  }
125
 
126
+ /**
127
+ * Import a theme from a zip file.
128
+ *
129
+ * This route is called when the Upload Theme button is pressed inside the
130
+ * admin area. It loads in the selected zip file for the theme and unpacks
131
+ * it in the uploads directory.
132
+ *
133
+ * @author Peter Featherstone <peter@featherstone.me>
134
+ *
135
+ * @since 3.1.16
136
+ *
137
+ * @param string $theme The theme file location to unzip
138
+ *
139
+ * @return string Output HTML from rendered view.
140
+ */
141
+ public function import_theme($theme) {
142
+ if($theme):
143
+ WP_Filesystem();
144
+ $upload_folder = wp_upload_dir()['basedir'] . '/responsive-menu-themes';
145
+
146
+ $unzipfile = unzip_file($theme, $upload_folder);
147
+
148
+ if(is_wp_error($unzipfile)) {
149
+ $alert = ['danger' => $unzipfile->get_error_message()];
150
+ } else {
151
+ $alert = ['success' => 'Responsive Menu Theme Imported Successfully.'];
152
+ }
153
+
154
+ else:
155
+ $alert = ['danger' => 'No import file selected'];
156
+
157
+ endif;
158
+
159
  return $this->view->render(
160
  'admin/main.html.twig',
161
  [
162
  'options' => $this->manager->all(),
163
+ 'alert' => $alert
 
 
164
  ]
165
  );
166
  }
167
 
168
+ /**
169
+ * Update the options based on submitted admin form.
170
+ *
171
+ * This route is called whenever the Update Options button is pressed and is
172
+ * the most commonly called route. Takes the submitted options and runs the
173
+ * update options task.
174
+ *
175
+ * @author Peter Featherstone <peter@featherstone.me>
176
+ *
177
+ * @since 3.0
178
+ *
179
+ * @param bool $valid_nonce Is the form nonce valid or not
180
+ * @param array $new_options An array of the submitted options.
181
+ *
182
+ * @return string Output HTML from rendered view.
183
+ */
184
+ public function update($valid_nonce, $new_options) {
185
  $validator = new Validator();
186
  $errors = [];
187
+
188
  if(!$valid_nonce):
189
  $alert = ['danger' => 'CSRF token not valid'];
190
  $options = new OptionsCollection($new_options);
191
+
192
  elseif($validator->validate($new_options)):
193
  try {
194
  $options = $this->manager->updateOptions($new_options);
195
  $task = new UpdateOptionsTask;
196
  $task->run($options, $this->view);
197
  $alert = ['success' => 'Responsive Menu Options Updated Successfully.'];
198
+
199
  } catch (\Exception $e) {
200
  $alert = ['danger' => $e->getMessage()];
201
  }
202
+
203
  else:
204
  $options = new OptionsCollection($new_options);
205
  $errors = $validator->getErrors();
206
  $alert = ['danger' => $errors];
207
+
208
  endif;
209
 
210
  return $this->view->render(
212
  [
213
  'options' => $options,
214
  'alert' => $alert,
 
 
215
  'errors' => $errors
216
  ]
217
  );
218
  }
219
 
220
+ /**
221
+ * Reset the options back to the defaults.
222
+ *
223
+ * This route is called whenever the Reset Options button is pressed. Resets
224
+ * all options back to their default states and runs the update options
225
+ * task.
226
+ *
227
+ * @author Peter Featherstone <peter@featherstone.me>
228
+ *
229
+ * @since 3.0
230
+ *
231
+ * @param array $default_options An array of the default options.
232
+ *
233
+ * @return string Output HTML from rendered view.
234
+ */
235
+ public function reset($default_options) {
236
  try {
237
  $options = $this->manager->updateOptions($default_options);
238
  $task = new UpdateOptionsTask;
239
  $task->run($options, $this->view);
240
  $alert = ['success' => 'Responsive Menu Options Reset Successfully'];
241
+
242
  } catch(\Exception $e) {
243
  $alert = ['danger' => $e->getMessage()];
244
  }
245
+
246
  return $this->view->render(
247
  'admin/main.html.twig',
248
  [
249
  'options' => $options,
250
+ 'alert' => $alert
 
 
251
  ]
252
  );
253
  }
254
 
255
+ /**
256
+ * Import options from a file.
257
+ *
258
+ * This route is called when the Import Options button is pressed inside the
259
+ * admin area. It loads in the selected json file and updates the options.
260
+ *
261
+ * @author Peter Featherstone <peter@featherstone.me>
262
+ *
263
+ * @since 3.0
264
+ *
265
+ * @param array $imported_options An array of the imported options.
266
+ *
267
+ * @return string Output HTML from rendered view.
268
+ */
269
+ public function import($imported_options) {
270
  $errors = [];
271
  if(!empty($imported_options)):
272
+
273
  $validator = new Validator();
274
  if($validator->validate($imported_options)):
275
  try {
282
  $options = $this->manager->all();
283
  $alert = ['danger' => $e->getMessage()];
284
  }
285
+
286
  else:
287
  $options = new OptionsCollection($imported_options);
288
  $errors = $validator->getErrors();
289
  $alert = ['danger' => $errors];
290
+
291
  endif;
292
+
293
  else:
294
  $options = $this->manager->all();
295
  $alert = ['danger' => 'No import file selected'];
296
+
297
  endif;
298
 
299
  return $this->view->render(
301
  [
302
  'options' => $options,
303
  'alert' => $alert,
 
 
304
  'errors' => $errors
305
  ]
306
  );
307
  }
308
 
309
+ /**
310
+ * Export all current options to a json file.
311
+ *
312
+ * This route is called when the Export Options button is pressed inside
313
+ * the admin area. It returns a json file of all the current options as a
314
+ * download attachment to the browser.
315
+ *
316
+ * @author Peter Featherstone <peter@featherstone.me>
317
+ *
318
+ * @since 3.0
319
+ *
320
+ * @return attachment json file attachment of plugin options.
321
+ */
322
  public function export() {
323
  return json_encode(
324
  $this->manager->all()->toArray()
app/Controllers/FrontController.php CHANGED
@@ -6,22 +6,87 @@ use ResponsiveMenu\View\View;
6
  use ResponsiveMenu\Management\OptionManager;
7
  use ResponsiveMenu\Formatters\Minifier;
8
 
 
 
 
 
 
 
 
 
 
 
9
  class FrontController {
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  public function __construct(OptionManager $manager, View $view) {
12
  $this->manager = $manager;
13
  $this->view = $view;
14
  }
15
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  public function index() {
17
  $options = $this->manager->all();
18
  $this->buildFrontEnd($options);
19
  }
20
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  public function preview() {
22
  return $this->view->render('preview.html.twig');
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  private function buildFrontEnd(OptionsCollection $options) {
26
  add_filter('body_class', function($classes) use($options) {
27
  $classes[] = 'responsive-menu-' . $options['animation_type'] . '-' . $options['menu_appear_from'];
6
  use ResponsiveMenu\Management\OptionManager;
7
  use ResponsiveMenu\Formatters\Minifier;
8
 
9
+ /**
10
+ * Entry point for all front end functionality.
11
+ *
12
+ * All routing for the front end comes through the functions below. When a
13
+ * front end page is loaded in the browser it will come through here.
14
+ *
15
+ * @author Peter Featherstone <peter@featherstone.me>
16
+ *
17
+ * @since 3.0
18
+ */
19
  class FrontController {
20
 
21
+ /**
22
+ * Constructor for setting up the FrontController.
23
+ *
24
+ * The constructor allows us to switch implementations for managing options
25
+ * and for rendering views. Useful for switching out mocked or stubbed
26
+ * classes during testing.
27
+ *
28
+ * @author Peter Featherstone <peter@featherstone.me>
29
+ *
30
+ * @since 3.0
31
+ *
32
+ * @param OptionManager $manager Instance of a Management options class.
33
+ * @param View $view Instance of a View class for rendering.
34
+ */
35
  public function __construct(OptionManager $manager, View $view) {
36
  $this->manager = $manager;
37
  $this->view = $view;
38
  }
39
 
40
+ /**
41
+ * Main route for the front end.
42
+ *
43
+ * This is the default view for the plugin on an initial GET request to the
44
+ * front end page.
45
+ *
46
+ * @author Peter Featherstone <peter@featherstone.me>
47
+ *
48
+ * @since 3.0
49
+ *
50
+ * @return string Output HTML from rendered view.
51
+ */
52
  public function index() {
53
  $options = $this->manager->all();
54
  $this->buildFrontEnd($options);
55
  }
56
 
57
+ /**
58
+ * Preview route for the front end.
59
+ *
60
+ * This is the preview view for the plugin when the preview admin option is
61
+ * pressed.
62
+ *
63
+ * @author Peter Featherstone <peter@featherstone.me>
64
+ *
65
+ * @since 3.0
66
+ *
67
+ * @return string Output HTML from rendered view.
68
+ */
69
  public function preview() {
70
  return $this->view->render('preview.html.twig');
71
  }
72
 
73
+ /**
74
+ * Helper private method to setup and build the front end.
75
+ *
76
+ * This is the preview view for the plugin when the preview admin option is
77
+ * pressed. We turn external files off to enable the preview options to
78
+ * take effect.
79
+ *
80
+ * TODO: This is a horrible method that really needs to be broken up in some
81
+ * way. There is a lot of setup and WordPress specific functionality going
82
+ * on here that would ideally be abstracted away.
83
+ *
84
+ * @author Peter Featherstone <peter@featherstone.me>
85
+ *
86
+ * @since 3.0
87
+ *
88
+ * @param OptionsCollection $options A OptionsCollection object.
89
+ */
90
  private function buildFrontEnd(OptionsCollection $options) {
91
  add_filter('body_class', function($classes) use($options) {
92
  $classes[] = 'responsive-menu-' . $options['animation_type'] . '-' . $options['menu_appear_from'];
config/default_options.php CHANGED
@@ -329,7 +329,8 @@ function get_responsive_menu_default_options() {
329
  'use_slide_effect' => 'off',
330
  'slide_effect_back_to_text' => 'Back',
331
 
332
- 'admin_theme' => 'dark'
 
333
 
334
  ];
335
 
329
  'use_slide_effect' => 'off',
330
  'slide_effect_back_to_text' => 'Back',
331
 
332
+ 'admin_theme' => 'dark',
333
+ 'menu_theme' => null
334
 
335
  ];
336
 
config/routing.php CHANGED
@@ -13,9 +13,6 @@ if(is_admin()):
13
  echo $controller->export();
14
  exit();
15
 
16
- elseif(isset($_POST['responsive-menu-rebuild-db']) && isset($_GET['page']) && $_GET['page'] == 'responsive-menu'):
17
- update_option('responsive_menu_version', '2.8.9');
18
-
19
  endif;
20
 
21
  add_menu_page(
@@ -25,34 +22,38 @@ if(is_admin()):
25
  'responsive-menu',
26
  function() {
27
  $controller = get_responsive_menu_service('admin_controller');
28
- $menus_array = [];
29
- $location_menus = ['' => 'None'];
30
- foreach(get_terms('nav_menu') as $menu) $menus_array[$menu->slug] = $menu->name;
31
- foreach(get_registered_nav_menus() as $location => $menu) $location_menus[$location] = $menu;
32
 
33
  if(isset($_POST['responsive-menu-current-page']))
34
  update_option('responsive_menu_current_page', $_POST['responsive-menu-current-page']);
35
 
36
  if(isset($_POST['responsive-menu-submit'])):
37
- update_option('hide_pro_options', isset($_POST['hide-pro-options']) ? "yes" : "no");
38
  $valid_nonce = wp_verify_nonce($_POST['responsive-menu-nonce'], 'update');
39
- echo $controller->update($valid_nonce, wp_unslash($_POST['menu']), $menus_array, $location_menus);
40
 
41
  elseif(isset($_POST['responsive-menu-reset'])):
42
- update_option('hide_pro_options', "no");
43
- echo $controller->reset(get_responsive_menu_default_options(), $menus_array, $location_menus);
 
 
44
 
45
  elseif(isset($_POST['responsive-menu-import'])):
46
  $file = $_FILES['responsive-menu-import-file'];
47
  $file_options = isset($file['tmp_name']) ? (array) json_decode(file_get_contents($file['tmp_name'])) : null;
48
- echo $controller->import($file_options, $menus_array, $location_menus);
 
 
 
 
 
 
 
49
 
50
  elseif(isset($_POST['responsive-menu-rebuild-db'])):
51
- update_option('hide_pro_options', "no");
52
- echo $controller->rebuild($menus_array, $location_menus);
53
 
54
  else:
55
- echo $controller->index($menus_array, $location_menus);
56
 
57
  endif;
58
  },
13
  echo $controller->export();
14
  exit();
15
 
 
 
 
16
  endif;
17
 
18
  add_menu_page(
22
  'responsive-menu',
23
  function() {
24
  $controller = get_responsive_menu_service('admin_controller');
 
 
 
 
25
 
26
  if(isset($_POST['responsive-menu-current-page']))
27
  update_option('responsive_menu_current_page', $_POST['responsive-menu-current-page']);
28
 
29
  if(isset($_POST['responsive-menu-submit'])):
30
+ update_option('hide_pro_options', isset($_POST['hide-pro-options']) ? 'yes' : 'no');
31
  $valid_nonce = wp_verify_nonce($_POST['responsive-menu-nonce'], 'update');
32
+ echo $controller->update($valid_nonce, wp_unslash($_POST['menu']));
33
 
34
  elseif(isset($_POST['responsive-menu-reset'])):
35
+ echo $controller->reset(get_responsive_menu_default_options());
36
+
37
+ elseif(isset($_POST['responsive-menu-theme'])):
38
+ echo $controller->apply_theme($_POST['menu']['menu_theme']);
39
 
40
  elseif(isset($_POST['responsive-menu-import'])):
41
  $file = $_FILES['responsive-menu-import-file'];
42
  $file_options = isset($file['tmp_name']) ? (array) json_decode(file_get_contents($file['tmp_name'])) : null;
43
+ echo $controller->import($file_options);
44
+
45
+
46
+ elseif(isset($_POST['responsive-menu-import-theme'])):
47
+ $file = $_FILES['responsive-menu-import-theme-file'];
48
+ $theme = isset($file['tmp_name']) && $file['tmp_name'] ? $file['tmp_name'] : null;
49
+
50
+ echo $controller->import_theme($theme);
51
 
52
  elseif(isset($_POST['responsive-menu-rebuild-db'])):
53
+ echo $controller->rebuild();
 
54
 
55
  else:
56
+ echo $controller->index();
57
 
58
  endif;
59
  },
config/twig.php CHANGED
@@ -84,10 +84,43 @@ else:
84
  $twig->addGlobal('admin_url', get_admin_url());
85
  $twig->addGlobal('shortcode', '[responsive_menu]');
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  $twig->addFunction(new Twig_SimpleFunction('hide_pro_options', function() {
88
  return get_option('hide_pro_options', 'no');
89
  }));
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  endif;
92
 
93
  $twig->addFilter(new Twig_SimpleFilter('json_decode', function($string) {
84
  $twig->addGlobal('admin_url', get_admin_url());
85
  $twig->addGlobal('shortcode', '[responsive_menu]');
86
 
87
+ $twig->addFunction(new Twig_SimpleFunction('get_available_themes', function() {
88
+ $theme_folder_path = wp_upload_dir()['basedir'] . '/responsive-menu-themes';
89
+ $theme_folders = glob($theme_folder_path . '/*' , GLOB_ONLYDIR);
90
+
91
+ $themes = [];
92
+ foreach($theme_folders as $theme_folder):
93
+ $config = json_decode(file_get_contents($theme_folder . '/config.json'), true);
94
+ $themes[basename($theme_folder)]['version'] = $config['version'];
95
+ $themes[basename($theme_folder)]['name'] = $config['name'];
96
+ endforeach;
97
+
98
+ return $themes;
99
+ }));
100
+
101
+ $twig->addGlobal('themes_folder_url', wp_upload_dir()['baseurl'] . '/responsive-menu-themes/');
102
+ $twig->addGlobal('themes_folder_dir', wp_upload_dir()['basedir'] . '/responsive-menu-themes/');
103
+
104
  $twig->addFunction(new Twig_SimpleFunction('hide_pro_options', function() {
105
  return get_option('hide_pro_options', 'no');
106
  }));
107
 
108
+ $twig->addFunction(new Twig_SimpleFunction('nav_menus', function() {
109
+ $menus_array = [];
110
+ foreach(get_terms('nav_menu') as $menu)
111
+ $menus_array[$menu->slug] = $menu->name;
112
+
113
+ return $menus_array;
114
+ }));
115
+
116
+ $twig->addFunction(new Twig_SimpleFunction('location_menus', function() {
117
+ $location_menus = ['' => 'None'];
118
+ foreach(get_registered_nav_menus() as $location => $menu)
119
+ $location_menus[$location] = $menu;
120
+
121
+ return $location_menus;
122
+ }));
123
+
124
  endif;
125
 
126
  $twig->addFilter(new Twig_SimpleFilter('json_decode', function($string) {
config/wp/scripts.php CHANGED
@@ -43,6 +43,7 @@ if(isset($_GET['page']) && $_GET['page'] == 'responsive-menu'):
43
 
44
  wp_register_script('responsive-menu-base-js', plugin_dir_url(dirname(dirname(__FILE__))) . 'public/js/admin/base.js', 'jquery', null);
45
  wp_localize_script('responsive-menu-base-js', 'WP_HOME_URL', home_url('/'));
 
46
  wp_enqueue_script('responsive-menu-base-js');
47
 
48
  wp_register_script('responsive-menu-additional-js', plugin_dir_url(dirname(dirname(__FILE__))) . 'public/js/admin/additional.js', 'jquery', null);
43
 
44
  wp_register_script('responsive-menu-base-js', plugin_dir_url(dirname(dirname(__FILE__))) . 'public/js/admin/base.js', 'jquery', null);
45
  wp_localize_script('responsive-menu-base-js', 'WP_HOME_URL', home_url('/'));
46
+ wp_localize_script('responsive-menu-base-js', 'THEMES_FOLDER_URL', wp_upload_dir()['baseurl'] . '/responsive-menu-themes/');
47
  wp_enqueue_script('responsive-menu-base-js');
48
 
49
  wp_register_script('responsive-menu-additional-js', plugin_dir_url(dirname(dirname(__FILE__))) . 'public/js/admin/additional.js', 'jquery', null);
public/css/admin/base.css CHANGED
@@ -319,7 +319,8 @@
319
  }
320
 
321
  #responsive-menu-admin #upgrade-banner,
322
- #responsive-menu-admin #docs-banner {
 
323
  background: #FAB719;
324
  padding: 35px;
325
  color: #333;
@@ -330,7 +331,8 @@
330
  }
331
 
332
  #responsive-menu-admin #upgrade-banner .button,
333
- #responsive-menu-admin #docs-banner .button {
 
334
  background: white;
335
  padding: 0 25px;
336
  height: 50px;
@@ -345,6 +347,12 @@
345
  margin-top: 15px;
346
  }
347
 
 
 
 
 
 
 
348
  #responsive-menu-admin #add-font-icon {
349
  margin-top: 15px;
350
  }
@@ -390,15 +398,15 @@
390
  border-bottom-style: solid;
391
  }
392
 
 
 
 
 
393
  #responsive-menu-admin .panel table td.col-left {
394
  border-right-width: 1px;
395
  border-right-style: solid;
396
  }
397
 
398
- #responsive-menu-admin .panel table td.col-right {
399
- position: relative;
400
- }
401
-
402
  #responsive-menu-admin .panel table tr:last-child td.col-left {
403
  border-bottom: 0;
404
  }
@@ -654,6 +662,15 @@
654
  margin-right: 8px;
655
  }
656
 
 
 
 
 
 
 
 
 
 
657
  @media screen and (max-width: 1600px) {
658
 
659
  #responsive-menu-admin .top-submit-buttons,
319
  }
320
 
321
  #responsive-menu-admin #upgrade-banner,
322
+ #responsive-menu-admin #docs-banner,
323
+ #responsive-menu-admin #themes-banner {
324
  background: #FAB719;
325
  padding: 35px;
326
  color: #333;
331
  }
332
 
333
  #responsive-menu-admin #upgrade-banner .button,
334
+ #responsive-menu-admin #docs-banner .button,
335
+ #responsive-menu-admin #themes-banner .button {
336
  background: white;
337
  padding: 0 25px;
338
  height: 50px;
347
  margin-top: 15px;
348
  }
349
 
350
+ #responsive-menu-admin #themes-banner {
351
+ background: #d9534f;
352
+ color: white;
353
+ margin-bottom: 15px;
354
+ }
355
+
356
  #responsive-menu-admin #add-font-icon {
357
  margin-top: 15px;
358
  }
398
  border-bottom-style: solid;
399
  }
400
 
401
+ #responsive-menu-admin .panel table td.col-right {
402
+ position: relative;
403
+ }
404
+
405
  #responsive-menu-admin .panel table td.col-left {
406
  border-right-width: 1px;
407
  border-right-style: solid;
408
  }
409
 
 
 
 
 
410
  #responsive-menu-admin .panel table tr:last-child td.col-left {
411
  border-bottom: 0;
412
  }
662
  margin-right: 8px;
663
  }
664
 
665
+ #responsive-menu-admin #responsive-menu-theme-container {
666
+ margin-top: 15px;
667
+ margin-right: 75px;
668
+ }
669
+
670
+ #responsive-menu-admin img#responsive-menu-theme-preview {
671
+ width: calc(100% - 75px);
672
+ }
673
+
674
  @media screen and (max-width: 1600px) {
675
 
676
  #responsive-menu-admin .top-submit-buttons,
public/js/admin/base.js CHANGED
@@ -190,4 +190,13 @@ jQuery(function($) {
190
  $('#sortable, .draggable').disableSelection();
191
  /* <-- End Menu Order Scripts */
192
 
 
 
 
 
 
 
 
 
 
193
  });
190
  $('#sortable, .draggable').disableSelection();
191
  /* <-- End Menu Order Scripts */
192
 
193
+ /* --> Theme Selector Script */
194
+ $('#responsive-menu-menu-theme').on('changed.bs.select', function() {
195
+ var selected_theme_key = $(this).val();
196
+ var preview_image_url = THEMES_FOLDER_URL + selected_theme_key + '/preview.png';
197
+ var $preview_image = $('#responsive-menu-theme-preview');
198
+
199
+ $preview_image.attr('src', preview_image_url);
200
+ });
201
+ /* <-- End Theme Selector Script */
202
  });
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: ResponsiveMenu, peterfeatherstone
3
  Tags: responsive, menu, responsive menu, mobile menu, wordpress responsive menu, wp responsive menu, tablet menu, hamburger menu, hamburger, mobile, tablet, 3 lines, 3 line, three line, three lines
4
  Requires at least: 3.6
5
  Tested up to: 4.9.7
6
- Stable tag: 3.1.15
7
  Requires PHP: 5.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -111,6 +111,9 @@ To view our FAQ, please go to [https://responsive.menu/faq/](https://responsive.
111
 
112
  == Changelog ==
113
 
 
 
 
114
  = 3.1.15 (26th July 2018) =
115
  * Fixed Sub Menu line height bug.
116
  * Removed Min Admin Guide.
3
  Tags: responsive, menu, responsive menu, mobile menu, wordpress responsive menu, wp responsive menu, tablet menu, hamburger menu, hamburger, mobile, tablet, 3 lines, 3 line, three line, three lines
4
  Requires at least: 3.6
5
  Tested up to: 4.9.7
6
+ Stable tag: 3.1.16
7
  Requires PHP: 5.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
111
 
112
  == Changelog ==
113
 
114
+ = 3.1.16 (15th August 2018) =
115
+ * Added ability to upload and use themes.
116
+
117
  = 3.1.15 (26th July 2018) =
118
  * Fixed Sub Menu line height bug.
119
  * Removed Min Admin Guide.
responsive-menu.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: Responsive Menu
5
  Plugin URI: https://responsive.menu
6
  Description: Highly Customisable Responsive Menu Plugin for WordPress
7
- Version: 3.1.15
8
  Author: Peter Featherstone
9
  Text Domain: responsive-menu
10
  Author URI: https://peterfeatherstone.com
4
  Plugin Name: Responsive Menu
5
  Plugin URI: https://responsive.menu
6
  Description: Highly Customisable Responsive Menu Plugin for WordPress
7
+ Version: 3.1.16
8
  Author: Peter Featherstone
9
  Text Domain: responsive-menu
10
  Author URI: https://peterfeatherstone.com
views/admin/banners.html.twig CHANGED
@@ -16,10 +16,15 @@
16
  <li>Preview Changes</li>
17
  <li>And much more</li>
18
  </ul>
19
- <a target="_blank" href="https://responsive.menu?utm_source=plugin&utm_medium=banner&utm_campaign=upgrade#pricing" class="button">Upgrade Today</a>
 
 
 
 
 
20
  </div>
21
 
22
  <div id="docs-banner">
23
  Confused? Check out our knowledgebase
24
- <a target="_blank" href="https://responsive.menu/knowledgebase?utm_source=plugin&utm_medium=banner&utm_campaign=knowledgebase" class="button">View Knowledgebase</a>
25
  </div>
16
  <li>Preview Changes</li>
17
  <li>And much more</li>
18
  </ul>
19
+ <a target="_blank" href="https://responsive.menu?utm_source=free-plugin&utm_medium=banner&utm_campaign=upgrade#pricing" class="button">Upgrade Today</a>
20
+ </div>
21
+
22
+ <div id="themes-banner">
23
+ Looking for some pre designed themes?
24
+ <a target="_blank" href="https://responsive.menu/themes?utm_source=free-plugin&utm_medium=banner&utm_campaign=themes" class="button">Buy some today</a>
25
  </div>
26
 
27
  <div id="docs-banner">
28
  Confused? Check out our knowledgebase
29
+ <a target="_blank" href="https://responsive.menu/knowledgebase?utm_source=free-plugin&utm_medium=banner&utm_campaign=knowledgebase" class="button">View Knowledgebase</a>
30
  </div>
views/admin/macros.html.twig CHANGED
@@ -246,6 +246,13 @@
246
  {{ macros.select(name, options[name], choices) }}
247
  {% elseif select_type == 'button_animation' %}
248
  {{ macros.button_animation_select(name, options[name]) }}
 
 
 
 
 
 
 
249
  {% endif %}
250
  {% elseif type == 'image' %}
251
  {{ macros.image(name, options[name]) }}
246
  {{ macros.select(name, options[name], choices) }}
247
  {% elseif select_type == 'button_animation' %}
248
  {{ macros.button_animation_select(name, options[name]) }}
249
+ {% elseif select_type == 'menu_theme' %}
250
+ {% set themes = get_available_themes() %}
251
+ {% set choices = [] %}
252
+ {% for theme, config in themes %}
253
+ {% set choices = choices|merge({(theme): config.name ~ ' (' ~ theme ~ ')'}) %}
254
+ {% endfor %}
255
+ {{ macros.select(name, options[name], choices) }}
256
  {% endif %}
257
  {% elseif type == 'image' %}
258
  {{ macros.image(name, options[name]) }}
views/admin/options.html.twig CHANGED
@@ -24,13 +24,16 @@
24
  <div id="technical" class="tab-pane fade{% if current_page() == 'technical' %} in active{% endif %}">
25
  {% include 'admin/sections/technical.html.twig' %}
26
  </div>
 
 
 
27
  <div id="header-bar" class="tab-pane fade{% if current_page() == 'header-bar' %} in active{% endif %}">
28
  {% include 'admin/sections/header-bar.html.twig' %}
29
  </div>
30
  <div id="desktop-menu" class="tab-pane fade{% if current_page() == 'desktop-menu' %} in active{% endif %}">
31
  {% include 'admin/sections/desktop-menu.html.twig' %}
32
  </div>
33
- <div id="advanced" class="tab-pane fade{% if current_page() == 'advanced' %} in active{% endif %}">
34
- {% include 'admin/sections/advanced.html.twig' %}
35
  </div>
36
  </div>
24
  <div id="technical" class="tab-pane fade{% if current_page() == 'technical' %} in active{% endif %}">
25
  {% include 'admin/sections/technical.html.twig' %}
26
  </div>
27
+ <div id="advanced" class="tab-pane fade{% if current_page() == 'advanced' %} in active{% endif %}">
28
+ {% include 'admin/sections/advanced.html.twig' %}
29
+ </div>
30
  <div id="header-bar" class="tab-pane fade{% if current_page() == 'header-bar' %} in active{% endif %}">
31
  {% include 'admin/sections/header-bar.html.twig' %}
32
  </div>
33
  <div id="desktop-menu" class="tab-pane fade{% if current_page() == 'desktop-menu' %} in active{% endif %}">
34
  {% include 'admin/sections/desktop-menu.html.twig' %}
35
  </div>
36
+ <div id="themes" class="tab-pane fade{% if current_page() == 'themes' %} in active{% endif %}">
37
+ {% include 'admin/sections/themes.html.twig' %}
38
  </div>
39
  </div>
views/admin/sections/advanced.html.twig CHANGED
@@ -21,7 +21,7 @@
21
  <table class='table table-bordered table-hover'>
22
  {{ macros.row('shortcode', 'Use Shortcode?', 'checkbox', options, errors, '', '', '', '', 'Please place ' ~ shortcode ~ ' in your files to use. Full documentation can be found <a href="https://responsive.menu/knowledgebase/using-the-shortcode/?utm_source=free-plugin&utm_medium=page&utm_campaign=using-the-shortcode" target="_blank">here</a>') }}
23
  {{ macros.row('hide_on_mobile', 'Hide on mobile devices', 'checkbox', options, errors, '', 'pro', '', '', 'This will disable the plugin on mobile devices. No HTML, CSS or JavaScript will be output if the user is on a mobile specific device.') }}
24
- {{ macros.row('hide_on_desktop', 'Hide on desktops', 'checkbox', options, errors, '', 'pro', '', '', 'This will disable the plugin on desktop devices. No HTML, CSS or JavaScript will be output if the user is on a mobile specific device.') }}
25
  {{ macros.row('show_menu_on_page_load', 'Show Menu on Page Load', 'checkbox', options, errors, '', 'pro', '', '', 'This will mean the menu container will show as opened and the button will be set to active on each page load.') }}
26
  {{ macros.row('menu_adjust_for_wp_admin_bar', 'Adjust for WP Admin Bar', 'checkbox', options, errors, '', 'pro', '', '', 'If you use the WP Admin bar when logged in, this will bring the various elements down so they are not hidden behind it.') }}
27
  {{ macros.row('menu_disable_scrolling', 'Disable Background Scrolling', 'checkbox', options, errors, '', 'pro', '', '', 'When the menu is open the background of the page cannot be scrolled.', '', '', 'Please ensure your theme follows WordPress theme development guidelines for this to work. Specifically that the html tag includes the language_attributes() function call.') }}
21
  <table class='table table-bordered table-hover'>
22
  {{ macros.row('shortcode', 'Use Shortcode?', 'checkbox', options, errors, '', '', '', '', 'Please place ' ~ shortcode ~ ' in your files to use. Full documentation can be found <a href="https://responsive.menu/knowledgebase/using-the-shortcode/?utm_source=free-plugin&utm_medium=page&utm_campaign=using-the-shortcode" target="_blank">here</a>') }}
23
  {{ macros.row('hide_on_mobile', 'Hide on mobile devices', 'checkbox', options, errors, '', 'pro', '', '', 'This will disable the plugin on mobile devices. No HTML, CSS or JavaScript will be output if the user is on a mobile specific device.') }}
24
+ {{ macros.row('hide_on_desktop', 'Hide on desktops', 'checkbox', options, errors, '', 'pro', '', '', 'This will disable the plugin on desktop devices. No HTML, CSS or JavaScript will be output if the user is on a desktop specific device.') }}
25
  {{ macros.row('show_menu_on_page_load', 'Show Menu on Page Load', 'checkbox', options, errors, '', 'pro', '', '', 'This will mean the menu container will show as opened and the button will be set to active on each page load.') }}
26
  {{ macros.row('menu_adjust_for_wp_admin_bar', 'Adjust for WP Admin Bar', 'checkbox', options, errors, '', 'pro', '', '', 'If you use the WP Admin bar when logged in, this will bring the various elements down so they are not hidden behind it.') }}
27
  {{ macros.row('menu_disable_scrolling', 'Disable Background Scrolling', 'checkbox', options, errors, '', 'pro', '', '', 'When the menu is open the background of the page cannot be scrolled.', '', '', 'Please ensure your theme follows WordPress theme development guidelines for this to work. Specifically that the html tag includes the language_attributes() function call.') }}
views/admin/sections/initial-setup.html.twig CHANGED
@@ -11,7 +11,7 @@
11
  {{ macros.header('Initial Setup', section) }}
12
  <table class='table table-bordered table-hover'>
13
  {{ macros.row('breakpoint', 'Breakpoint', 'input', options, errors, '', '', '', '', 'This is the width of the screen in pixels at which point you would like the hamburger button to start showing.', 'px', '', 'Set to 80000 if you want the menu to appear on all devices.') }}
14
- {{ macros.row('menu_to_use', 'Menu to Use', 'select', options, errors, '', '', 'custom', '', 'If no options appear here, make sure you have set them up under <strong>Appearance > Menus</strong> or click <a href="' ~ admin_url ~ 'nav-menus.php">here</a>.', '', nav_menus, 'Please note that the <a class="scroll-to-option" href="#responsive-menu-theme-location-menu">Theme Location</a> option will take precedence over this.') }}
15
- {{ macros.row('menu_to_hide', 'Original Menu to Hide', 'input', options, errors, '', '', '', '', 'To hide your current theme menu you need to put the CSS sleAny legal CSS selection criteria is valid here.', '', '', 'For example #nav-menu, nav, .other-nav') }}
16
  </table>
17
  </div>
11
  {{ macros.header('Initial Setup', section) }}
12
  <table class='table table-bordered table-hover'>
13
  {{ macros.row('breakpoint', 'Breakpoint', 'input', options, errors, '', '', '', '', 'This is the width of the screen in pixels at which point you would like the hamburger button to start showing.', 'px', '', 'Set to 80000 if you want the menu to appear on all devices.') }}
14
+ {{ macros.row('menu_to_use', 'Menu to Use', 'select', options, errors, '', '', 'custom', '', 'If no options appear here, make sure you have set them up under <strong>Appearance > Menus</strong> or click <a href="' ~ admin_url ~ 'nav-menus.php">here</a>.', '', nav_menus(), 'Please note that the <a class="scroll-to-option" href="#responsive-menu-theme-location-menu">Theme Location</a> option will take precedence over this.') }}
15
+ {{ macros.row('menu_to_hide', 'Original Menu to Hide', 'input', options, errors, '', '', '', '', 'To hide your current theme menu you need to put the CSS selector here. Any legal CSS selection criteria is valid.', '', '', 'For example #nav-menu, nav, .other-nav') }}
16
  </table>
17
  </div>
views/admin/sections/menu.html.twig CHANGED
@@ -145,7 +145,7 @@
145
  <div class='panel panel-default'>
146
  {{ macros.header('Advanced', section) }}
147
  <table class='table table-bordered table-hover'>
148
- {{ macros.row('theme_location_menu', 'Theme Location Menu', 'select', options, errors, '', '', 'custom', '', 'If you want to use a theme location menu rather than a specific menu then you can select that here.', '', location_menus, 'Please note that this will overwrite the <a class="scroll-to-option" href="#responsive-menu-menu-to-use">Menu to Use</a> option.') }}
149
  {{ macros.row('custom_walker', 'Custom Walker', 'input', options, errors, '', '', '', '', 'Set your own Walker class for customising the links HTML output.', '', '', 'Warning: For extremely advanced use only') }}
150
  </table>
151
  </div>
145
  <div class='panel panel-default'>
146
  {{ macros.header('Advanced', section) }}
147
  <table class='table table-bordered table-hover'>
148
+ {{ macros.row('theme_location_menu', 'Theme Location Menu', 'select', options, errors, '', '', 'custom', '', 'If you want to use a theme location menu rather than a specific menu then you can select that here.', '', location_menus(), 'Please note that this will overwrite the <a class="scroll-to-option" href="#responsive-menu-menu-to-use">Menu to Use</a> option.') }}
149
  {{ macros.row('custom_walker', 'Custom Walker', 'input', options, errors, '', '', '', '', 'Set your own Walker class for customising the links HTML output.', '', '', 'Warning: For extremely advanced use only') }}
150
  </table>
151
  </div>
views/admin/sections/modules/container-ordering.html.twig CHANGED
@@ -9,7 +9,7 @@
9
  <div class='sub-text'>Drag the container items up and down to re-order how they appear on the front end. You can also click to turn them on or off.</div>
10
  <div class='sub_sub_title'>Leaving the relevant options empty below will effectively turn them off.</div>
11
  </td>
12
- <td class='col-right'>
13
  <ul id='menu-sortable'>
14
  {% for key, selected in options.items_order|json_decode %}
15
  <li class='draggable'>
9
  <div class='sub-text'>Drag the container items up and down to re-order how they appear on the front end. You can also click to turn them on or off.</div>
10
  <div class='sub_sub_title'>Leaving the relevant options empty below will effectively turn them off.</div>
11
  </td>
12
+ <td class='col-right' style="padding-right: 90px;">
13
  <ul id='menu-sortable'>
14
  {% for key, selected in options.items_order|json_decode %}
15
  <li class='draggable'>
views/admin/sections/modules/desktop-menu-settings.html.twig CHANGED
@@ -47,7 +47,7 @@
47
  {% endfor %}
48
  </div>
49
 
50
- <div class="col-md-9 responsive-menu-desktop-menu-options-wrapper">
51
  {% for item in menu_items %}
52
  {% set has_title = false %}
53
  <div class="responsive-menu-desktop-menu-options-container" id="responsive-menu-desktop-menu-option-{{ item.ID }}">
47
  {% endfor %}
48
  </div>
49
 
50
+ <div class="col-md-9 responsive-menu-desktop-menu-options-wrapper" style="padding-right: 90px;">
51
  {% for item in menu_items %}
52
  {% set has_title = false %}
53
  <div class="responsive-menu-desktop-menu-options-container" id="responsive-menu-desktop-menu-option-{{ item.ID }}">
views/admin/sections/modules/rebuild.html.twig CHANGED
@@ -9,7 +9,7 @@
9
  <div class="sub-text">This will reset your plugin options back to their defaults.</div>
10
  <div class="sub_sub_title">Warning: This is a destructive process and can't be undone.</div>
11
  </td>
12
- <td class="col-right text-right">
13
  <button name='responsive-menu-reset' type='submit' class='btn btn-danger btn-lg btn-rm'>Reset Options</button>
14
  </td>
15
  </tr>
@@ -19,7 +19,7 @@
19
  <div class="sub-text">This will rebuild the database table if you are having issues.</div>
20
  <div class="sub_sub_title">Warning: This is a destructive process and can't be undone.</div>
21
  </td>
22
- <td class="col-right text-right">
23
  <button name='responsive-menu-rebuild-db' type='submit' class='btn btn-danger btn-lg btn-rm'>Rebuild Database</button>
24
  </td>
25
  </tr>
9
  <div class="sub-text">This will reset your plugin options back to their defaults.</div>
10
  <div class="sub_sub_title">Warning: This is a destructive process and can't be undone.</div>
11
  </td>
12
+ <td class="col-right text-right" style="padding-right: 90px;">
13
  <button name='responsive-menu-reset' type='submit' class='btn btn-danger btn-lg btn-rm'>Reset Options</button>
14
  </td>
15
  </tr>
19
  <div class="sub-text">This will rebuild the database table if you are having issues.</div>
20
  <div class="sub_sub_title">Warning: This is a destructive process and can't be undone.</div>
21
  </td>
22
+ <td class="col-right text-right" style="padding-right: 90px;">
23
  <button name='responsive-menu-rebuild-db' type='submit' class='btn btn-danger btn-lg btn-rm'>Rebuild Database</button>
24
  </td>
25
  </tr>
views/admin/sections/modules/transfer.html.twig CHANGED
@@ -9,7 +9,7 @@
9
  <div class="sub-text">This will import settings created via the Export process below.</div>
10
  <div class="sub_sub_title">Warning: This is a destructive process and can't be undone.</div>
11
  </td>
12
- <td class="col-right text-right">
13
  <input type='file' name='responsive-menu-import-file' />
14
  <button name='responsive-menu-import' type='submit' class='btn btn-primary btn-lg btn-rm'>Import</button>
15
  </td>
@@ -19,7 +19,7 @@
19
  <label class="control-label">Export</label>
20
  <div class="sub-text">This will create an export file for transferring to other sites.</div>
21
  </td>
22
- <td class="col-right text-right">
23
  <button name='responsive-menu-export' type='submit' class='btn btn-primary btn-lg btn-rm'>Export</button>
24
  </td>
25
  </tr>
9
  <div class="sub-text">This will import settings created via the Export process below.</div>
10
  <div class="sub_sub_title">Warning: This is a destructive process and can't be undone.</div>
11
  </td>
12
+ <td class="col-right text-right" style="padding-right: 90px;">
13
  <input type='file' name='responsive-menu-import-file' />
14
  <button name='responsive-menu-import' type='submit' class='btn btn-primary btn-lg btn-rm'>Import</button>
15
  </td>
19
  <label class="control-label">Export</label>
20
  <div class="sub-text">This will create an export file for transferring to other sites.</div>
21
  </td>
22
+ <td class="col-right text-right" style="padding-right: 90px;">
23
  <button name='responsive-menu-export' type='submit' class='btn btn-primary btn-lg btn-rm'>Export</button>
24
  </td>
25
  </tr>
views/admin/sections/themes.html.twig ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {#
2
+ Responsive Menu Jinja template file.
3
+ Safe to Copy
4
+ #}
5
+
6
+ {% import 'admin/macros.html.twig' as macros %}
7
+
8
+ {% set section = 'Themes' %}
9
+
10
+ <div class='panel panel-default'>
11
+ {{ macros.header('Theme', section) }}
12
+ <table class='table table-bordered table-hover'>
13
+ {% set themes = get_available_themes() %}
14
+ {{ macros.row('menu_theme', 'Menu Theme', 'select', options, errors, '', '', 'menu_theme', '', 'Pre-designed themes to help you get started.') }}
15
+ <tr>
16
+ <td class="col-left col-md-3"></td>
17
+ <td class="col-right text-right">
18
+ {% if themes %}
19
+ {% if options.menu_theme %}
20
+ {% set theme_slug = options.menu_theme %}
21
+ {% else %}
22
+ {% set theme_slug = themes|keys|first %}
23
+ {% endif %}
24
+ <div class="text-left">
25
+ <img id="responsive-menu-theme-preview" src="{{ themes_folder_url }}/{{ theme_slug }}/preview.png" />
26
+ </div>
27
+ <div id="responsive-menu-theme-container" class="text-center">
28
+ <p class="alert alert-info text-center">
29
+ Applying a theme will overwrite some of your current settings. Please <a class="scroll-to-option" href="#responsive-menu-export">export</a> current settings before applying new theme.
30
+ </p>
31
+ <button style="margin-left: 0;" name='responsive-menu-theme' id='responsive-menu-theme' type='submit' class='btn btn-primary btn-lg btn-rm'>Apply Theme</button>
32
+ </div>
33
+ {% else %}
34
+ <div class="text-center">
35
+ <p class="alert alert-warning text-center">
36
+ You don't appear to have any themes installed under <code>{{ themes_folder_dir }}</code> currently. Please check your file path or download some using the button below:<br /><br />
37
+ <a href="https://responsive.menu/themes" target="_blank" style="color: white; margin-left: 0;" class='btn btn-primary btn-lg btn-rm'>Get Themes</a>
38
+ </p>
39
+ </div>
40
+ {% endif %}
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <td class="col-left col-md-3">
45
+ <label class="control-label">Upload Theme</label>
46
+ <div class="sub-text">Import a zip file of a theme you have downloaded from <a href="https://responsive.menu/themes" target="_blank">https://responsive.menu/themes</a>.</div>
47
+ <div class="sub_sub_title">This will upload files to {{ themes_folder_dir }}.</div>
48
+ </td>
49
+ <td class="col-right text-right" style="padding-right: 90px;">
50
+ <input type='file' name='responsive-menu-import-theme-file' />
51
+ <button name='responsive-menu-import-theme' type='submit' class='btn btn-primary btn-lg btn-rm'>Upload</button>
52
+ <div class="alert alert-danger text-center">
53
+ Always be careful when uploading files from external locations. Ensure that the theme was downloaded directly from <a href="https://responsive.menu" target="_blank">https://responsive.menu</a>. All themes are checked by us before submission to the <a href="https://responsive.menu/themes" target="_blank">theme store</a>.
54
+ </div>
55
+ </td>
56
+ </tr>
57
+ </table>
58
+ </div>
views/admin/tabs.html.twig CHANGED
@@ -14,4 +14,5 @@
14
  <li class='{% if current_page() == 'advanced' %}active{% endif %}'><a data-toggle='tab' href='#advanced'>Advanced</a></li>
15
  <li class='{% if current_page() == 'header-bar' %}active {% endif %}pro-tab'><a data-toggle='tab' href='#header-bar'>Header Bar<span class='label label-danger'>Pro</span></a></li>
16
  <li class='{% if current_page() == 'desktop-menu' %}active {% endif %}pro-tab'><a data-toggle='tab' href='#desktop-menu'>Desktop Menu<span class='label label-danger'>Pro</span></a></li>
 
17
  </ul>
14
  <li class='{% if current_page() == 'advanced' %}active{% endif %}'><a data-toggle='tab' href='#advanced'>Advanced</a></li>
15
  <li class='{% if current_page() == 'header-bar' %}active {% endif %}pro-tab'><a data-toggle='tab' href='#header-bar'>Header Bar<span class='label label-danger'>Pro</span></a></li>
16
  <li class='{% if current_page() == 'desktop-menu' %}active {% endif %}pro-tab'><a data-toggle='tab' href='#desktop-menu'>Desktop Menu<span class='label label-danger'>Pro</span></a></li>
17
+ <li class='{% if current_page() == 'themes' %}active {% endif %}'><a data-toggle='tab' href='#themes'>Themes<span class='label label-danger'>New</span></a></li>
18
  </ul>