Responsive Menu - Version 3.1.0

Version Description

(25th April 2017) = * Requires PHP 5.4 * Massive overhaul of codebase * Speed improvements to front and back end * Admin now uses BootStrap * Twig templating engine implemented * Added admin form validation to help catch data errors * Added a rebuild database option * Done away with SASS on the fly compilation * Back to on slide effect now customisable - Pro only * Added option to adjust for WP Admin bar - Pro only * Bug fixes and compatibility fixes

Download this release

Release Info

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

Code changes from version 3.0.18 to 3.1.0

Files changed (237) hide show
  1. README.md +1 -0
  2. app/Collections/OptionsCollection.php +86 -0
  3. app/Container/Container.php +47 -0
  4. app/Controllers/AdminController.php +133 -0
  5. app/Controllers/FrontController.php +73 -0
  6. app/Database/Database.php +31 -0
  7. app/Database/Migration.php +36 -0
  8. app/Formatters/Minifier.php +24 -0
  9. app/Management/OptionManager.php +70 -0
  10. app/Tasks/UpdateOptionsTask.php +73 -0
  11. app/Validation/Validator.php +123 -0
  12. app/Validation/Validators/BaseValidator.php +19 -0
  13. app/Validation/Validators/Colour.php +24 -0
  14. app/Validation/Validators/Numeric.php +19 -0
  15. app/Validation/Validators/Positive.php +19 -0
  16. app/View/View.php +18 -0
  17. app/Walkers/Walker.php +129 -0
  18. autoload.php +0 -15
  19. composer.json +10 -0
  20. composer.lock +81 -0
  21. config/default_options.php +208 -0
  22. config/polylang.php +18 -0
  23. config/routing.php +56 -0
  24. config/services.php +42 -0
  25. config/twig.php +54 -0
  26. config/wp/scripts.php +38 -0
  27. migration.php +37 -0
  28. public/css/admin/admin.css +391 -0
  29. public/css/admin/bootstrap-select.css +6 -0
  30. public/css/admin/bootstrap-toggle.css +28 -0
  31. public/css/admin/bootstrap.css +6 -0
  32. public/css/admin/minicolours.css +323 -0
  33. public/css/animations/boring.css.twig +19 -0
  34. tests/app/Form/FontIconPageListTest.php → public/css/animations/off.css.twig +0 -0
  35. public/css/app.css.twig +517 -0
  36. public/fonts/admin/glyphicons-halflings-regular.eot +0 -0
  37. public/fonts/admin/glyphicons-halflings-regular.svg +288 -0
  38. public/fonts/admin/glyphicons-halflings-regular.ttf +0 -0
  39. public/fonts/admin/glyphicons-halflings-regular.woff +0 -0
  40. public/fonts/admin/glyphicons-halflings-regular.woff2 +0 -0
  41. public/js/admin/admin.js +77 -0
  42. public/js/admin/bootstrap-file.js +1 -0
  43. public/js/admin/bootstrap-select.js +9 -0
  44. public/js/admin/bootstrap-toggle.js +9 -0
  45. public/js/admin/bootstrap.js +7 -0
  46. public/js/admin/minicolours.js +11 -0
  47. public/js/app.js.twig +175 -0
  48. readme.txt +18 -13
  49. responsive-menu.php +36 -40
  50. src/app/Collections/OptionsCollection.php +0 -83
  51. src/app/Controllers/Admin.php +0 -60
  52. src/app/Controllers/Front.php +0 -38
  53. src/app/Database/Database.php +0 -10
  54. src/app/Database/Migration.php +0 -193
  55. src/app/Database/WpDatabase.php +0 -52
  56. src/app/Factories/CssFactory.php +0 -30
  57. src/app/Factories/JsFactory.php +0 -26
  58. src/app/Factories/OptionFactory.php +0 -27
  59. src/app/Filesystem/FileCreator.php +0 -22
  60. src/app/Filesystem/FolderCreator.php +0 -15
  61. src/app/Filesystem/ScriptsBuilder.php +0 -38
  62. src/app/Filters/Filter.php +0 -7
  63. src/app/Filters/HtmlFilter.php +0 -11
  64. src/app/Filters/JsonFilter.php +0 -11
  65. src/app/Filters/TextFilter.php +0 -11
  66. src/app/Form/Checkbox.php +0 -22
  67. src/app/Form/Colour.php +0 -13
  68. src/app/Form/Export.php +0 -11
  69. src/app/Form/FontIconPageList.php +0 -74
  70. src/app/Form/FormComponent.php +0 -8
  71. src/app/Form/HeaderBarOrdering.php +0 -49
  72. src/app/Form/Image.php +0 -14
  73. src/app/Form/Import.php +0 -11
  74. src/app/Form/MenuOrdering.php +0 -48
  75. src/app/Form/Reset.php +0 -11
  76. src/app/Form/Select.php +0 -22
  77. src/app/Form/Text.php +0 -13
  78. src/app/Form/TextArea.php +0 -13
  79. src/app/Formatters/Minify.php +0 -24
  80. src/app/Mappers/JsMapper.php +0 -196
  81. src/app/Mappers/ScssBaseMapper.php +0 -201
  82. src/app/Mappers/ScssButtonMapper.php +0 -63
  83. src/app/Mappers/ScssMapper.php +0 -11
  84. src/app/Mappers/ScssMenuMapper.php +0 -207
  85. src/app/Mappers/scss.inc.php +0 -4577
  86. src/app/Models/Option.php +0 -45
  87. src/app/Repositories/OptionRepository.php +0 -56
  88. src/app/Routing/Container.php +0 -47
  89. src/app/Services/OptionService.php +0 -57
  90. src/app/Translation/Translator.php +0 -41
  91. src/app/View/AdminView.php +0 -50
  92. src/app/View/FrontView.php +0 -73
  93. src/app/View/View.php +0 -8
  94. src/app/ViewModels/Button.php +0 -17
  95. src/app/ViewModels/Components/Admin/Boxes.php +0 -113
  96. src/app/ViewModels/Components/Admin/Tabs.php +0 -28
  97. src/app/ViewModels/Components/Button/Button.php +0 -39
  98. src/app/ViewModels/Components/ComponentFactory.php +0 -21
  99. src/app/ViewModels/Components/Menu/AdditionalContent.php +0 -23
  100. src/app/ViewModels/Components/Menu/Menu.php +0 -35
  101. src/app/ViewModels/Components/Menu/Search.php +0 -24
  102. src/app/ViewModels/Components/Menu/Title.php +0 -48
  103. src/app/ViewModels/Components/ViewComponent.php +0 -11
  104. src/app/ViewModels/Menu.php +0 -23
  105. src/app/Walkers/WpWalker.php +0 -131
  106. src/config/admin_ordering.php +0 -1505
  107. src/config/default_options.php +0 -202
  108. src/config/internationalise.php +0 -29
  109. src/config/option_helpers.php +0 -22
  110. src/config/routing.php +0 -55
  111. src/config/services.php +0 -164
  112. src/config/setup.php +0 -7
  113. src/public/css/admin/main.css +0 -767
  114. src/public/js/admin/main.js +0 -54
  115. src/public/scss/hamburgers/_base.scss +0 -69
  116. src/public/scss/hamburgers/hamburgers.scss +0 -57
  117. src/public/scss/hamburgers/types/_boring.scss +0 -30
  118. src/views/admin/main.phtml +0 -102
  119. src/views/button.phtml +0 -1
  120. src/views/menu.phtml +0 -8
  121. src/views/preview.phtml +0 -16
  122. tests/app/Collections/OptionsCollectionTest.php +128 -132
  123. tests/app/Container/ContainerTest.php +66 -0
  124. tests/app/Controllers/AdminControllerTest.php +21 -0
  125. tests/app/Controllers/AdminTest.php +0 -57
  126. tests/app/Controllers/FrontTest.php +0 -37
  127. tests/app/Database/MigrationTest.php +72 -104
  128. tests/app/Database/WpDatabaseTest.php +0 -55
  129. tests/app/Factories/CssFactoryTest.php +0 -35
  130. tests/app/Factories/JsFactoryTest.php +0 -30
  131. tests/app/Factories/OptionFactoryTest.php +0 -61
  132. tests/app/Filesystem/FileCreatorTest.php +0 -25
  133. tests/app/Filesystem/FolderCreatorTest.php +0 -21
  134. tests/app/Filesystem/ScriptsBuilderTest.php +0 -23
  135. tests/app/Filters/HtmlFilterTest.php +0 -15
  136. tests/app/Filters/JsonFilterTest.php +0 -19
  137. tests/app/Filters/TextFilterTest.php +0 -19
  138. tests/app/Form/CheckboxTest.php +0 -33
  139. tests/app/Form/ColourTest.php +0 -16
  140. tests/app/Form/ExportTest.php +0 -16
  141. tests/app/Form/FontIconTest.php +0 -23
  142. tests/app/Form/HeaderBarOrderingTest.php +0 -18
  143. tests/app/Form/ImageTest.php +0 -17
  144. tests/app/Form/ImportTest.php +0 -16
  145. tests/app/Form/MenuOrderingTest.php +0 -17
  146. tests/app/Form/ResetTest.php +0 -16
  147. tests/app/Form/SelectTest.php +0 -47
  148. tests/app/Form/TextAreaTest.php +0 -16
  149. tests/app/Form/TextTest.php +0 -16
  150. tests/app/Formatters/MinifierTest.php +28 -0
  151. tests/app/Formatters/MinifyTest.php +0 -27
  152. tests/app/Management/OptionManagerTest.php +85 -0
  153. tests/app/Mappers/JsMapperTest.php +0 -59
  154. tests/app/Mappers/ScssBaseMapperTest.php +0 -32
  155. tests/app/Mappers/ScssButtonMapperTest.php +0 -42
  156. tests/app/Mappers/ScssMenuMapperTest.php +0 -83
  157. tests/app/Models/OptionTest.php +0 -57
  158. tests/app/Repositories/OptionRepositoryTest.php +0 -87
  159. tests/app/Routing/ContainerTest.php +0 -66
  160. tests/app/Services/OptionsServiceTest.php +0 -59
  161. tests/app/Translation/TranslatorTest.php +0 -50
  162. tests/app/Validation/ValidatorTest.php +47 -0
  163. tests/app/Validation/Validators/ColourTest.php +40 -0
  164. tests/app/Validation/Validators/NumericTest.php +47 -0
  165. tests/app/Validation/Validators/PositiveTest.php +41 -0
  166. tests/app/View/AdminViewTest.php +0 -19
  167. tests/app/View/FrontViewTest.php +0 -18
  168. tests/app/ViewModels/ButtonTest.php +0 -18
  169. tests/app/ViewModels/Components/Admin/BoxesTest.php +0 -50
  170. tests/app/ViewModels/Components/Admin/TabsTest.php +0 -24
  171. tests/app/ViewModels/Components/Button/ButtonTest.php +0 -36
  172. tests/app/ViewModels/Components/ComponentFactoryTest.php +0 -27
  173. tests/app/ViewModels/Components/Menu/AdditionalContentTest.php +0 -28
  174. tests/app/ViewModels/Components/Menu/MenuTest.php +0 -36
  175. tests/app/ViewModels/Components/Menu/SearchTest.php +0 -21
  176. tests/app/ViewModels/Components/Menu/TitleTest.php +0 -32
  177. tests/app/ViewModels/MenuTest.php +0 -32
  178. tests/app/Walkers/WpWalkerTest.php +0 -93
  179. tests/scssc/ApiTest.php +0 -80
  180. tests/scssc/InputTest.php +0 -80
  181. tests/scssc/compare-scss.sh +0 -25
  182. tests/scssc/inputs/builtins.scss +0 -171
  183. tests/scssc/inputs/comments.scss +0 -28
  184. tests/scssc/inputs/compass_extract.scss +0 -248
  185. tests/scssc/inputs/content.scss +0 -61
  186. tests/scssc/inputs/content_with_function.scss +0 -17
  187. tests/scssc/inputs/default_args.scss +0 -15
  188. tests/scssc/inputs/directives.scss +0 -108
  189. tests/scssc/inputs/extends.scss +0 -184
  190. tests/scssc/inputs/filter_effects.scss +0 -48
  191. tests/scssc/inputs/functions.scss +0 -81
  192. tests/scssc/inputs/ie7.scss +0 -12
  193. tests/scssc/inputs/if.scss +0 -76
  194. tests/scssc/inputs/if_on_null.scss +0 -8
  195. tests/scssc/inputs/import.scss +0 -23
  196. tests/scssc/inputs/imports/_partial.scss +0 -10
  197. tests/scssc/inputs/imports/simple.scss +0 -4
  198. tests/scssc/inputs/interpolation.scss +0 -86
  199. tests/scssc/inputs/keyword_args.scss +0 -24
  200. tests/scssc/inputs/list.scss +0 -15
  201. tests/scssc/inputs/looping.scss +0 -51
  202. tests/scssc/inputs/media.scss +0 -208
  203. tests/scssc/inputs/mixins.scss +0 -158
  204. tests/scssc/inputs/nesting.scss +0 -45
  205. tests/scssc/inputs/null.scss +0 -41
  206. tests/scssc/inputs/operators.scss +0 -143
  207. tests/scssc/inputs/placeholder_selector.scss +0 -18
  208. tests/scssc/inputs/scss_css.scss +0 -986
  209. tests/scssc/inputs/selectors.scss +0 -187
  210. tests/scssc/inputs/values.scss +0 -43
  211. tests/scssc/inputs/variables.scss +0 -56
  212. tests/scssc/outputs/builtins.css +0 -126
  213. tests/scssc/outputs/comments.css +0 -19
  214. tests/scssc/outputs/compass_extract.css +0 -28
  215. tests/scssc/outputs/content.css +0 -29
  216. tests/scssc/outputs/content_with_function.css +0 -2
  217. tests/scssc/outputs/default_args.css +0 -3
  218. tests/scssc/outputs/directives.css +0 -77
  219. tests/scssc/outputs/extends.css +0 -87
  220. tests/scssc/outputs/filter_effects.css +0 -20
  221. tests/scssc/outputs/functions.css +0 -22
  222. tests/scssc/outputs/ie7.css +0 -8
  223. tests/scssc/outputs/if.css +0 -21
  224. tests/scssc/outputs/if_on_null.css +0 -2
  225. tests/scssc/outputs/import.css +0 -27
  226. tests/scssc/outputs/interpolation.css +0 -54
  227. tests/scssc/outputs/keyword_args.css +0 -6
  228. tests/scssc/outputs/list.css +0 -7
  229. tests/scssc/outputs/looping.css +0 -45
  230. tests/scssc/outputs/media.css +0 -103
  231. tests/scssc/outputs/mixins.css +0 -83
  232. tests/scssc/outputs/nesting.css +0 -22
  233. tests/scssc/outputs/null.css +0 -21
  234. tests/scssc/outputs/operators.css +0 -105
  235. tests/scssc/outputs/placeholder_selector.css +0 -7
  236. tests/scssc/outputs/scss_css.css +0 -741
  237. tests/scssc/outputs/selectors.css +0 -22
README.md ADDED
@@ -0,0 +1 @@
 
1
+ [ ![Codeship Status](https://www.codeship.io/projects/0f626140-0c02-0135-749e-1e85f2753028/status?branch=master)](https://app.codeship.com/projects/215186)
app/Collections/OptionsCollection.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Collections;
4
+
5
+ class OptionsCollection implements \ArrayAccess, \Countable {
6
+
7
+ private $options;
8
+
9
+ public function __construct(array $options = []) {
10
+ $this->options = array_map(function($o) {
11
+ return is_array($o) ? stripslashes(json_encode($o)) : stripslashes($o);
12
+ }, $options);
13
+ }
14
+
15
+ public function add(array $option) {
16
+ $value = $option[key($option)];
17
+ $this->options[key($option)] = is_array($value) ? stripslashes(json_encode($value)) : stripslashes($value);
18
+ }
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
+ else
24
+ return $this->options['active_arrow_shape'];
25
+
26
+ }
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
+ else
32
+ return $this->options['inactive_arrow_shape'];
33
+
34
+ }
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
+ else
40
+ return null;
41
+
42
+ }
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
+ else
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) {
57
+ return array_key_exists($offset, $this->options);
58
+ }
59
+
60
+ public function offsetGet($offset) {
61
+ if(isset($this->options[$offset]))
62
+ return $this->options[$offset];
63
+ return null;
64
+ }
65
+
66
+ public function offsetSet($offset, $value) {
67
+ $this->options[$offset] = $value;
68
+ }
69
+
70
+ public function offsetUnset($offset) {
71
+ if(isset($this->options[$offset]))
72
+ unset($this->options[$offset]);
73
+ }
74
+
75
+ public function toArray() {
76
+ $array = [];
77
+ foreach($this->options as $key => $val)
78
+ $array[$key] = $val;
79
+ return $array;
80
+ }
81
+
82
+ public function count() {
83
+ return count($this->options);
84
+ }
85
+
86
+ }
app/Container/Container.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Container;
4
+
5
+ class Container implements \ArrayAccess {
6
+
7
+ private $values = [];
8
+ private $raw = [];
9
+ private $keys = [];
10
+
11
+ public function offsetSet($id, $value) {
12
+ $this->values[$id] = $value;
13
+ $this->keys[$id] = true;
14
+ }
15
+
16
+ public function offsetGet($id) {
17
+
18
+ if(!isset($this->keys[$id])) {
19
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
20
+ }
21
+
22
+ if(isset($this->raw[$id]) || !is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
23
+ return $this->values[$id];
24
+ }
25
+
26
+ $raw = $this->values[$id];
27
+ $val = $this->values[$id] = $raw($this);
28
+ $this->raw[$id] = $this->values[$id];
29
+
30
+ return $this->values[$id];
31
+ }
32
+
33
+ public function offsetExists($id) {
34
+ return isset($this->keys[$id]);
35
+ }
36
+
37
+ public function offsetUnset($id) {
38
+ if(isset($this->keys[$id])) {
39
+ unset($this->values[$id], $this->raw[$id], $this->keys[$id]);
40
+ }
41
+ }
42
+
43
+ public function keys() {
44
+ return array_keys($this->values);
45
+ }
46
+
47
+ }
app/Controllers/AdminController.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Controllers;
4
+ use ResponsiveMenu\View\View;
5
+ use ResponsiveMenu\Management\OptionManager;
6
+ 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($new_options, $nav_menus, $location_menus) {
41
+ $validator = new Validator();
42
+ $errors = [];
43
+ if($validator->validate($new_options)):
44
+ try {
45
+ $options = $this->manager->updateOptions($new_options);
46
+ $task = new UpdateOptionsTask;
47
+ $task->run($options, $this->view);
48
+ $alert = ['success' => 'Responsive Menu Options Updated Successfully.'];
49
+ } catch (\Exception $e) {
50
+ $alert = ['danger' => $e->getMessage()];
51
+ }
52
+ else:
53
+ $options = new OptionsCollection($new_options);
54
+ $errors = $validator->getErrors();
55
+ $alert = ['danger' => $errors];
56
+ endif;
57
+
58
+ return $this->view->render(
59
+ 'admin/main.html.twig',
60
+ [
61
+ 'options' => $options,
62
+ 'alert' => $alert,
63
+ 'nav_menus' => $nav_menus,
64
+ 'location_menus' => $location_menus,
65
+ 'errors' => $errors
66
+ ]
67
+ );
68
+ }
69
+
70
+ public function reset($default_options, $nav_menus, $location_menus) {
71
+ try {
72
+ $options = $this->manager->updateOptions($default_options);
73
+ $task = new UpdateOptionsTask;
74
+ $task->run($options, $this->view);
75
+ $alert = ['success' => 'Responsive Menu Options Reset Successfully'];
76
+ } catch(\Exception $e) {
77
+ $alert = ['danger' => $e->getMessage()];
78
+ }
79
+ return $this->view->render(
80
+ 'admin/main.html.twig',
81
+ [
82
+ 'options' => $options,
83
+ 'alert' => $alert,
84
+ 'nav_menus' => $nav_menus,
85
+ 'location_menus' => $location_menus
86
+ ]
87
+ );
88
+ }
89
+
90
+ public function import($imported_options, $nav_menus, $location_menus) {
91
+ if(!empty($imported_options)):
92
+ $validator = new Validator();
93
+ $errors = [];
94
+ if($validator->validate($imported_options)):
95
+ try {
96
+ unset($imported_options['button_click_trigger']);
97
+ $options = $this->manager->updateOptions($imported_options);
98
+ $task = new UpdateOptionsTask;
99
+ $task->run($options, $this->view);
100
+ $alert = ['success' => 'Responsive Menu Options Imported Successfully.'];
101
+ } catch(\Exception $e) {
102
+ $options = $this->manager->all();
103
+ $alert = ['danger' => $e->getMessage()];
104
+ }
105
+ else:
106
+ $options = new OptionsCollection($imported_options);
107
+ $errors = $validator->getErrors();
108
+ $alert = ['danger' => $errors];
109
+ endif;
110
+ else:
111
+ $options = $this->manager->all();
112
+ $alert = ['danger' => 'No import file selected'];
113
+ endif;
114
+
115
+ return $this->view->render(
116
+ 'admin/main.html.twig',
117
+ [
118
+ 'options' => $options,
119
+ 'alert' => $alert,
120
+ 'nav_menus' => $nav_menus,
121
+ 'location_menus' => $location_menus,
122
+ 'errors' => $errors
123
+ ]
124
+ );
125
+ }
126
+
127
+ public function export() {
128
+ return json_encode(
129
+ $this->manager->all()->toArray()
130
+ );
131
+ }
132
+
133
+ }
app/Controllers/FrontController.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Controllers;
4
+ use ResponsiveMenu\Collections\OptionsCollection;
5
+ 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'];
28
+ return $classes;
29
+ });
30
+
31
+ if($options['external_files'] == 'on'):
32
+ $css_file = plugins_url() . '/responsive-menu-data/css/responsive-menu-' . get_current_blog_id() . '.css';
33
+ $js_file = plugins_url() . '/responsive-menu-data/js/responsive-menu-' . get_current_blog_id() . '.js';
34
+ wp_enqueue_style('responsive-menu', $css_file, null, false);
35
+ wp_enqueue_script('responsive-menu', $js_file, ['jquery'], false, $options['scripts_in_footer'] == 'on' ? true : false);
36
+ else:
37
+ add_action('wp_head', function() use($options) {
38
+ $css_data = $this->view->render('css/app.css.twig', ['options' => $options]);
39
+ if($options['minify_scripts'] == 'on')
40
+ $css_data = Minifier::minify($css_data);
41
+
42
+ echo '<style>' . $css_data . '</style>';
43
+ }, 100);
44
+
45
+ add_action($options['scripts_in_footer'] == 'on' ? 'wp_footer' : 'wp_head', function() use($options) {
46
+ $js_data = $this->view->render('js/app.js.twig', ['options' => $options]);
47
+ if($options['minify_scripts'] == 'on')
48
+ $js_data = Minifier::minify($js_data);
49
+
50
+ echo '<script>' . $js_data . '</script>';
51
+ }, 100);
52
+ endif;
53
+
54
+ if($options['shortcode'] == 'on'):
55
+ add_shortcode('responsive_menu', function($atts) use($options) {
56
+
57
+ if(is_array($atts))
58
+ $merged_options = array_merge($options->toArray(), $atts);
59
+ else
60
+ $merged_options = $options->toArray();
61
+
62
+ $new_collection = new OptionsCollection($merged_options);
63
+ return $this->view->render('app.html.twig', ['options' => $new_collection]);
64
+ });
65
+ else:
66
+ add_action('wp_footer', function() use($options) {
67
+ echo $this->view->render('app.html.twig', ['options' => $options]);
68
+ });
69
+ endif;
70
+
71
+ }
72
+
73
+ }
app/Database/Database.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Database;
4
+
5
+ class Database {
6
+
7
+ public function __construct($db_base) {
8
+ $this->db = $db_base;
9
+ }
10
+
11
+ public function all($table) {
12
+ $results = $this->db->get_results("SELECT * FROM {$this->db->prefix}{$table}", ARRAY_A);
13
+ $flattened = [];
14
+ foreach($results as $result)
15
+ $flattened[$result['name']] = $result['value'];
16
+ return $flattened;
17
+ }
18
+
19
+ public function update($table, array $to_update, array $where) {
20
+ return $this->db->update($this->db->prefix . $table, $to_update, $where);
21
+ }
22
+
23
+ public function delete($table, $name) {
24
+ return $this->db->delete($this->db->prefix . $table, $name);
25
+ }
26
+
27
+ public function insert($table, array $arguments) {
28
+ return $this->db->insert($this->db->prefix . $table, $arguments);
29
+ }
30
+
31
+ }
app/Database/Migration.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Database;
4
+ use ResponsiveMenu\Management\OptionManager;
5
+
6
+ class Migration {
7
+
8
+ private $manager;
9
+ private $old_version;
10
+ private $new_version;
11
+ private $defaults;
12
+
13
+ public function __construct(OptionManager $manager, $old_version, $new_version, $defaults) {
14
+ $this->manager = $manager;
15
+ $this->old_version = $old_version;
16
+ $this->new_version = $new_version;
17
+ $this->defaults = $defaults;
18
+ }
19
+
20
+ public function needsTable() {
21
+ return substr($this->old_version, 0, 1) < 3;
22
+ }
23
+
24
+ public function needsUpdate() {
25
+ return version_compare($this->old_version, $this->new_version, '<');
26
+ }
27
+
28
+ public function addNewOptions() {
29
+ return $this->manager->createOptions(array_diff_key($this->defaults, $this->manager->all()->toArray()));
30
+ }
31
+
32
+ public function tidyUpOptions() {
33
+ return $this->manager->removeOptions(array_diff_key($this->manager->all()->toArray(), $this->defaults));
34
+ }
35
+
36
+ }
app/Formatters/Minifier.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Formatters;
4
+
5
+ class Minifier {
6
+
7
+ public static function minify($data) {
8
+
9
+ /* remove comments */
10
+ $minified = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $data);
11
+
12
+ /* remove tabs, spaces, newlines, etc. */
13
+ $minified = str_replace(array("\r\n","\r","\n","\t",' ',' ',' '), '', $minified);
14
+
15
+ /* remove other spaces before/after ; */
16
+ $minified = preg_replace(array('(( )+{)','({( )+)'), '{', $minified);
17
+ $minified = preg_replace(array('(( )+})','(}( )+)','(;( )*})'), '}', $minified);
18
+ $minified = preg_replace(array('(;( )+)','(( )+;)'), ';', $minified);
19
+
20
+ return $minified;
21
+
22
+ }
23
+
24
+ }
app/Management/OptionManager.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Management;
4
+ use ResponsiveMenu\Collections\OptionsCollection;
5
+ use ResponsiveMenu\Database\Database;
6
+
7
+ class OptionManager {
8
+
9
+ private $db;
10
+ private $default_options;
11
+
12
+ public function __construct(Database $db, $default_options) {
13
+ $this->db = $db;
14
+ $this->default_options = $default_options;
15
+ }
16
+
17
+ public function all() {
18
+ $options = $this->db->all('responsive_menu');
19
+ return new OptionsCollection($options);
20
+ }
21
+
22
+ public function updateOptions(array $options) {
23
+ $updated_options = $this->combineOptions($options);
24
+ foreach($updated_options as $name => $val):
25
+ $val = is_array($val) ? json_encode($val) : $val;
26
+ $val = stripslashes($val);
27
+ $updated_options[$name] = $val;
28
+ $this->db->update('responsive_menu', ['value' => $val], ['name' => $name]);
29
+ endforeach;
30
+ return new OptionsCollection($updated_options);
31
+ }
32
+
33
+ public function createOptions(array $options) {
34
+ $updated_options = $this->combineOptions($options);
35
+ foreach($options as $name => $val):
36
+ $val = is_array($val) ? json_encode($val) : $val;
37
+ $val = stripslashes($val);
38
+ $updated_options[$name] = $val;
39
+ $this->db->insert('responsive_menu', ['name' => $name, 'value' => $val]);
40
+ endforeach;
41
+ return new OptionsCollection($updated_options);
42
+ }
43
+
44
+ public function removeOptions(array $options) {
45
+ $updated_options = $this->combineOptions($options);
46
+ foreach($options as $name => $val):
47
+ $val = is_array($val) ? json_encode($val) : $val;
48
+ $val = stripslashes($val);
49
+ $updated_options[$name] = $val;
50
+ unset($updated_options[$name]);
51
+ $this->db->delete('responsive_menu', ['name' => $name]);
52
+ endforeach;
53
+ return new OptionsCollection($updated_options);
54
+ }
55
+
56
+ public function buildFromArray(array $options) {
57
+ $new_options = $this->combineOptions($options);
58
+ foreach($options as $name => $val):
59
+ $val = is_array($val) ? json_encode($val) : $val;
60
+ $val = stripslashes($val);
61
+ $new_options[$name] = $val;
62
+ endforeach;
63
+ return new OptionsCollection($new_options);
64
+ }
65
+
66
+ private function combineOptions($new_options) {
67
+ return array_merge($this->default_options, $new_options);
68
+ }
69
+
70
+ }
app/Tasks/UpdateOptionsTask.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Tasks;
4
+ use ResponsiveMenu\Collections\OptionsCollection;
5
+ use ResponsiveMenu\Formatters\Minifier;
6
+ use ResponsiveMenu\View\View;
7
+
8
+ class UpdateOptionsTask {
9
+
10
+ private $translatables = [
11
+ 'menu_to_use',
12
+ 'button_title',
13
+ 'menu_title',
14
+ 'menu_title_link',
15
+ 'menu_additional_content'
16
+ ];
17
+
18
+ public function run(OptionsCollection $options, View $view) {
19
+ /*
20
+ * Build CSS and Js files
21
+ *
22
+ */
23
+ if($options['external_files'] == 'on'):
24
+
25
+ $base_dir = dirname(dirname(dirname(dirname(__FILE__)))) . '/responsive-menu-data';
26
+
27
+ if(!is_dir($base_dir))
28
+ if(!mkdir($base_dir))
29
+ throw new \Exception('You don\'t have permissions to create data folder - please check permissions.');
30
+
31
+ if(!is_dir($base_dir . '/css'))
32
+ if(!mkdir($base_dir . '/css'))
33
+ throw new \Exception('You don\'t have permissions to create CSS data folder - please check permissions.');
34
+
35
+ if(!is_dir($base_dir . '/js'))
36
+ if(!mkdir($base_dir . '/js'))
37
+ throw new \Exception('You don\'t have permissions to create JS data folder - please check permissions.');
38
+
39
+ $css_file = $base_dir . '/css/responsive-menu-' . get_current_blog_id() . '.css';
40
+ $css_data = $view->render('css/app.css.twig', ['options' => $options]);
41
+
42
+ if($options['minify_scripts'] == 'on')
43
+ $css_data = Minifier::minify($css_data);
44
+
45
+ if(!file_put_contents($css_file, $css_data))
46
+ throw new \Exception('You don\'t have permissions to write external CSS file - please check permissions.');
47
+
48
+ $js_file = $base_dir . '/js/responsive-menu-' . get_current_blog_id() . '.js';
49
+ $js_data = $view->render('js/app.js.twig', ['options' => $options]);
50
+
51
+ if($options['minify_scripts'] == 'on')
52
+ $js_data = Minifier::minify($js_data);
53
+
54
+ if(!file_put_contents($js_file, $js_data)):
55
+ throw new \Exception('You don\'t have permissions to write external JS file - please check permissions.');
56
+ endif;
57
+
58
+ else:
59
+ /*
60
+ * TODO: Do some tidy up like removing external files if this option is not set - be a good citizen!
61
+ */
62
+ endif;
63
+
64
+ /*
65
+ * Update translations for WPML
66
+ */
67
+ foreach($this->translatables as $option_name)
68
+ if(isset($options[$option_name]))
69
+ do_action('wpml_register_single_string', 'Responsive Menu', $option_name, $options[$option_name]);
70
+
71
+ }
72
+
73
+ }
app/Validation/Validator.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Validation;
4
+
5
+ class Validator {
6
+
7
+ private $errors;
8
+
9
+ public function validate($options) {
10
+ foreach($this->validation_map as $validator_name => $options_list):
11
+ foreach($options_list as $option):
12
+ if(isset($options[$option])):
13
+ $validator_obj = 'ResponsiveMenu\Validation\Validators\\' . $validator_name;
14
+ $validator = new $validator_obj($options[$option]);
15
+ if(!$validator->validate()):
16
+ $nice_name = str_replace('_', ' ', ucwords($option));
17
+ $this->errors[$option][] = 'Validation failed on <a class="validation-error" href="#responsive-menu-' . str_replace('_', '-', $option) . '">' . $nice_name . '</a>: ' . $validator->getErrorMessage();
18
+ endif;
19
+ endif;
20
+ endforeach;
21
+ endforeach;
22
+
23
+ if(!empty($this->errors))
24
+ return false;
25
+
26
+ return true;
27
+ }
28
+
29
+ public function getErrors() {
30
+ return $this->errors;
31
+ }
32
+
33
+ private $validation_map = [
34
+
35
+ // Numeric Validators
36
+ 'Numeric' => [
37
+ 'breakpoint',
38
+ 'button_line_width',
39
+ 'button_line_height',
40
+ 'button_line_margin',
41
+ 'button_width',
42
+ 'button_height',
43
+ 'button_top',
44
+ 'animation_speed',
45
+ 'transition_speed',
46
+ 'button_font_size',
47
+ 'button_title_line_height',
48
+ 'menu_width',
49
+ 'menu_title_font_size',
50
+ 'menu_border_width',
51
+ 'menu_font_size',
52
+ 'menu_links_height',
53
+ 'submenu_arrow_height',
54
+ 'submenu_arrow_width',
55
+ 'header_bar_height',
56
+ 'header_bar_font_size',
57
+ 'single_menu_height',
58
+ 'single_menu_font_size',
59
+ 'single_menu_submenu_font_size',
60
+ 'single_menu_submenu_height',
61
+ ],
62
+
63
+ // Positive Digits
64
+ 'Positive' => [
65
+ 'breakpoint',
66
+ ],
67
+
68
+ // Colour Validators
69
+ 'Colour' => [
70
+ 'button_background_colour',
71
+ 'button_background_colour_hover',
72
+ 'button_line_colour',
73
+ 'button_text_colour',
74
+ 'menu_background_colour',
75
+ 'menu_item_background_colour',
76
+ 'menu_item_background_hover_colour',
77
+ 'menu_item_border_colour',
78
+ 'menu_item_border_colour_hover',
79
+ 'menu_title_background_colour',
80
+ 'menu_title_background_hover_colour',
81
+ 'menu_current_item_background_colour',
82
+ 'menu_current_item_background_hover_colour',
83
+ 'menu_current_item_border_colour',
84
+ 'menu_current_item_border_hover_colour',
85
+ 'menu_title_colour',
86
+ 'menu_title_hover_colour',
87
+ 'menu_link_colour',
88
+ 'menu_link_hover_colour',
89
+ 'menu_current_link_colour',
90
+ 'menu_current_link_hover_colour',
91
+ 'menu_sub_arrow_border_colour',
92
+ 'menu_sub_arrow_border_hover_colour',
93
+ 'menu_sub_arrow_border_colour_active',
94
+ 'menu_sub_arrow_border_hover_colour_active',
95
+ 'menu_sub_arrow_background_colour',
96
+ 'menu_sub_arrow_background_hover_colour',
97
+ 'menu_sub_arrow_background_colour_active',
98
+ 'menu_sub_arrow_background_hover_colour_active',
99
+ 'menu_sub_arrow_shape_colour',
100
+ 'menu_sub_arrow_shape_hover_colour',
101
+ 'menu_sub_arrow_shape_colour_active',
102
+ 'menu_sub_arrow_shape_hover_colour_active',
103
+ 'menu_additional_content_colour',
104
+ 'menu_overlay_colour',
105
+ 'menu_search_box_text_colour',
106
+ 'menu_search_box_border_colour',
107
+ 'menu_search_box_background_colour',
108
+ 'menu_search_box_placeholder_colour',
109
+ 'single_menu_item_link_colour',
110
+ 'single_menu_item_link_colour_hover',
111
+ 'single_menu_item_background_colour',
112
+ 'single_menu_item_background_colour_hover',
113
+ 'single_menu_item_submenu_link_colour',
114
+ 'single_menu_item_submenu_link_colour_hover',
115
+ 'single_menu_item_submenu_background_colour',
116
+ 'single_menu_item_submenu_background_colour_hover',
117
+ 'header_bar_background_color',
118
+ 'header_bar_text_color',
119
+ ]
120
+
121
+ ];
122
+
123
+ }
app/Validation/Validators/BaseValidator.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Validation\Validators;
4
+
5
+ abstract class BaseValidator {
6
+
7
+ protected $error;
8
+ protected $data;
9
+
10
+ abstract public function validate();
11
+
12
+ public function __construct($data) {
13
+ $this->data = $data;
14
+ }
15
+
16
+ public function getErrorMessage() {
17
+ return $this->error;
18
+ }
19
+ }
app/Validation/Validators/Colour.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Validation\Validators;
4
+
5
+ class Colour extends BaseValidator {
6
+
7
+ public function validate() {
8
+ $valid_colour = false;
9
+
10
+ // First check valid Hex
11
+ if(preg_match('/^#(?:[0-9a-f]{3}){1,2}$/i', $this->data))
12
+ $valid_colour = true;
13
+
14
+ // Next check valid rgba()
15
+ if(preg_match('/rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)/i', $this->data))
16
+ $valid_colour = true;
17
+
18
+ if(!$valid_colour)
19
+ $this->error = 'Invalid colour value';
20
+
21
+ return $valid_colour;
22
+ }
23
+
24
+ }
app/Validation/Validators/Numeric.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Validation\Validators;
4
+
5
+ class Numeric extends BaseValidator {
6
+
7
+ public function validate() {
8
+ $valid_integer = false;
9
+
10
+ if(is_numeric($this->data))
11
+ $valid_integer = true;
12
+
13
+ if(!$valid_integer)
14
+ $this->error = 'Invalid number';
15
+
16
+ return $valid_integer;
17
+ }
18
+
19
+ }
app/Validation/Validators/Positive.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Validation\Validators;
4
+
5
+ class Positive extends BaseValidator {
6
+
7
+ public function validate() {
8
+ $is_positive = false;
9
+
10
+ if($this->data >= 0)
11
+ $is_positive = true;
12
+
13
+ if(!$is_positive)
14
+ $this->error = 'Number must be 0 or positive';
15
+
16
+ return $is_positive;
17
+ }
18
+
19
+ }
app/View/View.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\View;
4
+ use \Twig_Environment;
5
+
6
+ class View {
7
+
8
+ protected $twig;
9
+
10
+ public function __construct(Twig_Environment $twig) {
11
+ $this->twig = $twig;
12
+ }
13
+
14
+ public function render($location, $options = []) {
15
+ return $this->twig->render($location, $options);
16
+ }
17
+
18
+ }
app/Walkers/Walker.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ResponsiveMenu\Walkers;
4
+ use ResponsiveMenu\Collections\OptionsCollection;
5
+
6
+ class Walker extends \Walker_Nav_Menu {
7
+
8
+ private $current_item;
9
+
10
+ public function __construct(OptionsCollection $options) {
11
+ $this->options = $options;
12
+ }
13
+
14
+ public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
15
+
16
+ $this->setCurrentItem($item);
17
+
18
+ $classes = empty($item->classes) ? array() : (array) $item->classes;
19
+ $responsive_menu_classes = $classes;
20
+
21
+ # Turn into our Responsive Menu Classes
22
+ foreach($classes as $class):
23
+ switch($class):
24
+ case 'menu-item': $responsive_menu_classes[] = 'responsive-menu-item'; break;
25
+ case 'current-menu-item': $responsive_menu_classes[] = 'responsive-menu-current-item'; break;
26
+ case 'menu-item-has-children': $responsive_menu_classes[] = 'responsive-menu-item-has-children'; break;
27
+ case 'current-menu-parent': $responsive_menu_classes[] = 'responsive-menu-item-current-parent'; break;
28
+ case 'current-menu-ancestor': $responsive_menu_classes[] = 'responsive-menu-item-current-ancestor'; break;
29
+ endswitch;
30
+ endforeach;
31
+
32
+ /* Clear child class if we are at the final depth level */
33
+ if(isset($responsive_menu_classes)):
34
+ if($depth + 1 == $this->options['menu_depth'] && ($key = array_search('responsive-menu-item-has-children', $responsive_menu_classes)) !== false) {
35
+ unset($responsive_menu_classes[$key]);
36
+ }
37
+ endif;
38
+
39
+ $class_names = join(' ', array_unique($responsive_menu_classes));
40
+ $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
41
+
42
+ $id = ' id="responsive-menu-item-' . esc_attr( $item->ID ) . '"';
43
+
44
+ $output .= '<li' . $id . $class_names .'>';
45
+
46
+ $atts = array();
47
+ $atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : '';
48
+ $atts['target'] = ! empty( $item->target ) ? $item->target : '';
49
+ $atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
50
+ $atts['href'] = ! empty( $item->url ) ? $item->url : '';
51
+ $atts['class'] = 'responsive-menu-item-link';
52
+
53
+ $atts = apply_filters('nav_menu_link_attributes', $atts, $item, $args, $depth);
54
+
55
+ $attributes = '';
56
+ foreach ($atts as $attr => $value) {
57
+ if (!empty( $value)) {
58
+ $value = ('href' === $attr ) ? esc_url( $value) : esc_attr($value);
59
+ $attributes .= ' ' . $attr . '="' . $value . '"';
60
+ }
61
+ }
62
+
63
+ $title = apply_filters('the_title', $item->title, $item->ID);
64
+ $title = apply_filters('nav_menu_item_title', $title, $item, $args, $depth);
65
+
66
+ /* Calculate which arrow to show */
67
+ if(in_array('responsive-menu-item-has-children', $responsive_menu_classes)):
68
+ $inactive_arrow = '<div class="responsive-menu-subarrow">' . $this->options->getInActiveArrow() . '</div>';
69
+ $active_arrow = '<div class="responsive-menu-subarrow responsive-menu-subarrow-active">' . $this->options->getActiveArrow() . '</div>';
70
+ if($this->options['auto_expand_all_submenus'] == 'on'):
71
+ $initial_arrow = $active_arrow;
72
+ elseif(
73
+ $this->options['auto_expand_current_submenus'] == 'on' && (in_array('responsive-menu-item-current-parent', $responsive_menu_classes)
74
+ || in_array('responsive-menu-item-current-ancestor', $responsive_menu_classes))):
75
+ $initial_arrow = $active_arrow;
76
+ else:
77
+ $initial_arrow = $inactive_arrow;
78
+ endif;
79
+ else:
80
+ $initial_arrow = '';
81
+ endif;
82
+
83
+ /* Clear Arrow if we are at the final depth level */
84
+ if($depth + 1 == $this->options['menu_depth'])
85
+ $initial_arrow = '';
86
+
87
+ $item_output = '<a'. $attributes .'>';
88
+ $item_output .= $title;
89
+ $item_output .= $initial_arrow;
90
+ $item_output .= '</a>';
91
+
92
+ $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
93
+
94
+ }
95
+
96
+ public function start_lvl(&$output, $depth = 0, $args = array()) {
97
+ $output .= "<ul class='responsive-menu-submenu responsive-menu-submenu-depth-" . ($depth + 1) . $this->getSubmenuClassOpenOrNot() . "'>";
98
+ }
99
+
100
+ public function end_el(&$output, $item, $depth = 0, $args = array()) {
101
+ $output .= "</li>";
102
+ }
103
+
104
+ public function end_lvl(&$output, $depth = 0, $args = array()) {
105
+ $output .= "</ul>";
106
+ }
107
+
108
+ public function setCurrentItem($item) {
109
+ $this->current_item = $item;
110
+ }
111
+
112
+ public function getCurrentItem() {
113
+ return $this->current_item;
114
+ }
115
+
116
+ public function getSubmenuClassOpenOrNot() {
117
+ return $this->expandAllSubmenuOptionsIsOn() || $this->expandCurrentSubmenuOnAndItemIsParent() ? ' responsive-menu-submenu-open' : '';
118
+ }
119
+
120
+ public function expandAllSubmenuOptionsIsOn() {
121
+ return $this->options['auto_expand_all_submenus'] == 'on';
122
+ }
123
+
124
+ public function expandCurrentSubmenuOnAndItemIsParent() {
125
+ return ($this->options['auto_expand_current_submenus'] == 'on')
126
+ && ($this->getCurrentItem()->current_item_ancestor || $this->getCurrentItem()->current_item_parent);
127
+ }
128
+
129
+ }
autoload.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- require_once dirname(__FILE__) . '/src/app/Mappers/scss.inc.php';
4
-
5
- spl_autoload_register( function( $class_name ) {
6
-
7
- $strip_namespace = str_replace( 'ResponsiveMenu\\', '', $class_name );
8
- $file_name = str_replace( '\\', '/', $strip_namespace );
9
-
10
- $file = __DIR__ . '/src/app/' . $file_name . '.php';
11
-
12
- if(file_exists($file))
13
- include $file;
14
-
15
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
composer.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "require": {
3
+ "twig/twig": "1.33.0"
4
+ },
5
+ "autoload": {
6
+ "psr-4": {
7
+ "ResponsiveMenu\\": "app/"
8
+ }
9
+ }
10
+ }
composer.lock ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "hash": "802aa0021594e5acc4c74c035325ace1",
8
+ "content-hash": "3e0253c4e4a1ebc6bc87d8ca2e86e719",
9
+ "packages": [
10
+ {
11
+ "name": "twig/twig",
12
+ "version": "v1.33.0",
13
+ "source": {
14
+ "type": "git",
15
+ "url": "https://github.com/twigphp/Twig.git",
16
+ "reference": "05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a"
17
+ },
18
+ "dist": {
19
+ "type": "zip",
20
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a",
21
+ "reference": "05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a",
22
+ "shasum": ""
23
+ },
24
+ "require": {
25
+ "php": ">=5.2.7"
26
+ },
27
+ "require-dev": {
28
+ "psr/container": "^1.0",
29
+ "symfony/debug": "~2.7",
30
+ "symfony/phpunit-bridge": "~3.3@dev"
31
+ },
32
+ "type": "library",
33
+ "extra": {
34
+ "branch-alias": {
35
+ "dev-master": "1.33-dev"
36
+ }
37
+ },
38
+ "autoload": {
39
+ "psr-0": {
40
+ "Twig_": "lib/"
41
+ }
42
+ },
43
+ "notification-url": "https://packagist.org/downloads/",
44
+ "license": [
45
+ "BSD-3-Clause"
46
+ ],
47
+ "authors": [
48
+ {
49
+ "name": "Fabien Potencier",
50
+ "email": "fabien@symfony.com",
51
+ "homepage": "http://fabien.potencier.org",
52
+ "role": "Lead Developer"
53
+ },
54
+ {
55
+ "name": "Armin Ronacher",
56
+ "email": "armin.ronacher@active-4.com",
57
+ "role": "Project Founder"
58
+ },
59
+ {
60
+ "name": "Twig Team",
61
+ "homepage": "http://twig.sensiolabs.org/contributors",
62
+ "role": "Contributors"
63
+ }
64
+ ],
65
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
66
+ "homepage": "http://twig.sensiolabs.org",
67
+ "keywords": [
68
+ "templating"
69
+ ],
70
+ "time": "2017-03-22 15:40:09"
71
+ }
72
+ ],
73
+ "packages-dev": [],
74
+ "aliases": [],
75
+ "minimum-stability": "stable",
76
+ "stability-flags": [],
77
+ "prefer-stable": false,
78
+ "prefer-lowest": false,
79
+ "platform": [],
80
+ "platform-dev": []
81
+ }
config/default_options.php ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function get_responsive_menu_default_options() {
4
+
5
+ return [
6
+
7
+ 'breakpoint' => 8000,
8
+ 'menu_to_hide' => '',
9
+ 'menu_depth' => 5,
10
+ 'menu_to_use' => '',
11
+ 'theme_location_menu' => '',
12
+
13
+ // Button Settings
14
+ 'button_title' => null,
15
+ 'button_image' => null,
16
+ 'button_image_alt' => null,
17
+ 'button_image_when_clicked' => null,
18
+ 'button_image_alt_when_clicked' => null,
19
+ 'button_font' => null,
20
+ 'button_font_icon' => null,
21
+ 'button_font_icon_when_clicked' => null,
22
+ 'button_click_trigger' => '#responsive-menu-button',
23
+ 'button_title_position' => 'left',
24
+ 'button_title_line_height' => '13',
25
+ 'button_title_line_height_unit' => 'px',
26
+ 'button_background_colour' => '#000',
27
+ 'button_background_colour_hover' => '#000',
28
+ 'button_click_animation' => 'boring',
29
+ 'button_line_colour' => '#fff',
30
+ 'button_text_colour' => '#fff',
31
+ 'button_transparent_background' => 'off',
32
+ 'button_width' => 55,
33
+ 'button_width_unit' => 'px',
34
+ 'button_height' => 55,
35
+ 'button_height_unit' => 'px',
36
+ 'button_line_margin' => 5,
37
+ 'button_line_margin_unit' => 'px',
38
+ 'button_line_height' => 3,
39
+ 'button_line_height_unit' => 'px',
40
+ 'button_line_width' => 25,
41
+ 'button_line_width_unit' => 'px',
42
+ 'button_top' => 15,
43
+ 'button_top_unit' => 'px',
44
+ 'button_distance_from_side' => 5,
45
+ 'button_distance_from_side_unit' => '%',
46
+ 'button_left_or_right' => 'right',
47
+ 'button_position_type' => 'fixed',
48
+ 'button_push_with_animation' => 'off',
49
+ 'button_font_size' => 14,
50
+ 'button_font_size_unit' => 'px',
51
+
52
+ // Animation Settings
53
+ 'animation_type' => 'slide',
54
+ 'page_wrapper' => null,
55
+ 'animation_speed' => 0.5,
56
+ 'transition_speed' => 0.5,
57
+
58
+ // Menu Settings
59
+ 'active_arrow_shape' => '▲',
60
+ 'inactive_arrow_shape' => '▼',
61
+ 'active_arrow_image' => '',
62
+ 'active_arrow_image_alt' => '',
63
+ 'inactive_arrow_image' => '',
64
+ 'inactive_arrow_image_alt' => '',
65
+ 'active_arrow_font_icon' => '',
66
+ 'inactive_arrow_font_icon' => '',
67
+ 'arrow_position' => 'right',
68
+ 'submenu_arrow_width' => '40',
69
+ 'submenu_arrow_width_unit' => 'px',
70
+ 'submenu_arrow_height' => '40',
71
+ 'submenu_arrow_height_unit' => 'px',
72
+ 'accordion_animation' => 'off',
73
+ 'auto_expand_all_submenus' => 'off',
74
+ 'auto_expand_current_submenus' => 'off',
75
+
76
+ 'menu_background_colour' => '#212121',
77
+ 'menu_background_image' => '',
78
+ 'menu_item_background_colour' => '#212121',
79
+ 'menu_item_background_hover_colour' => '#3f3f3f',
80