Easing Slider - Version 3.0.0

Version Description

  • A complete internal rebuild, now fully compatible with current versions of WordPress and those coming in the future. Marks the start of a new product direction for Easing Slider, and a renewed committment to continued development!
Download this release

Release Info

Developer MatthewRuddy
Plugin Icon 128x128 Easing Slider
Version 3.0.0
Comparing to
See all releases

Code changes from version 2.2.1.1 to 3.0.0

Files changed (270) hide show
  1. .bowerrc +3 -0
  2. Gruntfile.js +148 -0
  3. css/editor-pages.css → assets/css/admin.css +367 -34
  4. assets/css/admin.min.css +1 -0
  5. assets/css/public.css +465 -0
  6. assets/css/public.min.css +1 -0
  7. {images → assets/images}/easingslider-badge.jpg +0 -0
  8. {images → assets/images}/function-screenshot.jpg +0 -0
  9. {images → assets/images}/interface-screenshot.jpg +0 -0
  10. {images → assets/images}/list-screenshot.jpg +0 -0
  11. {images → assets/images}/loading.gif +0 -0
  12. {images → assets/images}/loading@2x.gif +0 -0
  13. {images → assets/images}/nav-arrow-next.png +0 -0
  14. {images → assets/images}/nav-arrow-next@2x.png +0 -0
  15. {images → assets/images}/nav-arrow-prev.png +0 -0
  16. {images → assets/images}/nav-arrow-prev@2x.png +0 -0
  17. {images → assets/images}/nav-icon-active.png +0 -0
  18. {images → assets/images}/nav-icon-active@2x.png +0 -0
  19. {images → assets/images}/nav-icon-inactive.png +0 -0
  20. {images → assets/images}/nav-icon-inactive@2x.png +0 -0
  21. assets/images/placeholder-pixel.png +0 -0
  22. {images → assets/images}/pro-bundle.png +0 -0
  23. {images → assets/images}/shadow.png +0 -0
  24. {images → assets/images}/shortcode-screenshot.jpg +0 -0
  25. {images → assets/images}/welcome-screenshot.jpg +0 -0
  26. {images → assets/images}/widget-screenshot.jpg +0 -0
  27. assets/js/admin.js +2157 -0
  28. assets/js/admin.min.js +1 -0
  29. assets/js/public.js +1635 -0
  30. assets/js/public.min.js +1 -0
  31. backbone/slide.php +0 -49
  32. bower.json +19 -0
  33. css/customizer.css +0 -12
  34. css/customizer.min.css +0 -1
  35. css/easingslider.css +0 -707
  36. css/easingslider.min.css +0 -1
  37. css/editor-pages.min.css +0 -1
  38. css/extensions-page.css +0 -34
  39. css/extensions-page.min.css +0 -1
  40. css/settings-page.css +0 -30
  41. css/settings-page.min.css +0 -1
  42. css/welcome-pages.css +0 -44
  43. css/welcome-pages.min.css +0 -1
  44. easing-slider.php +65 -378
  45. images/nav-play.png +0 -0
  46. images/nav-play@2x.png +0 -0
  47. includes/class-es-customizations.php +0 -262
  48. includes/class-es-customizer-legacy.php +0 -262
  49. includes/class-es-customizer-notice.php +0 -86
  50. includes/class-es-customizer.php +0 -231
  51. includes/class-es-editor-pages.php +0 -414
  52. includes/class-es-extensions-page.php +0 -156
  53. includes/class-es-image-resizer.php +0 -234
  54. includes/class-es-legacy.php +0 -704
  55. includes/class-es-menu.php +0 -109
  56. includes/class-es-migrations.php +0 -105
  57. includes/class-es-settings-page.php +0 -205
  58. includes/class-es-shortcode.php +0 -170
  59. includes/class-es-slider.php +0 -823
  60. includes/class-es-sliders-list-table.php +0 -424
  61. includes/class-es-update-manager.php +0 -473
  62. includes/class-es-welcome-pages.php +0 -205
  63. includes/class-es-widget.php +0 -121
  64. includes/helpers.php +0 -238
  65. js/customizer.js +0 -197
  66. js/customizer.min.js +0 -1
  67. js/editor-pages.js +0 -1274
  68. js/editor-pages.min.js +0 -1
  69. js/jquery.easingslider.js +0 -593
  70. js/jquery.easingslider.min.js +0 -1
  71. languages/easing-slider.pot +0 -1103
  72. languages/easingslider.pot +491 -0
  73. package.json +15 -0
  74. partials/customizer.php +0 -161
  75. partials/discover-extensions.php +0 -26
  76. partials/edit-settings.php +0 -40
  77. partials/edit-settings_general.php +0 -65
  78. partials/edit-settings_licenses.php +0 -12
  79. partials/edit-slider.php +0 -73
  80. partials/edit-slider_sidebar.php +0 -410
  81. partials/list-sliders.php +0 -35
  82. partials/welcome.php +0 -18
  83. partials/welcome_about.php +0 -48
  84. partials/welcome_credits.php +0 -28
  85. partials/welcome_getting-started.php +0 -64
  86. readme.txt +36 -20
  87. resources/assets/css/admin.css +791 -0
  88. resources/assets/css/public.css +230 -0
  89. resources/assets/images/easingslider-badge.jpg +0 -0
  90. resources/assets/images/function-screenshot.jpg +0 -0
  91. resources/assets/images/interface-screenshot.jpg +0 -0
  92. resources/assets/images/list-screenshot.jpg +0 -0
  93. resources/assets/images/loading.gif +0 -0
  94. resources/assets/images/loading@2x.gif +0 -0
  95. resources/assets/images/nav-arrow-next.png +0 -0
  96. resources/assets/images/nav-arrow-next@2x.png +0 -0
  97. resources/assets/images/nav-arrow-prev.png +0 -0
  98. resources/assets/images/nav-arrow-prev@2x.png +0 -0
  99. resources/assets/images/nav-icon-active.png +0 -0
  100. resources/assets/images/nav-icon-active@2x.png +0 -0
  101. resources/assets/images/nav-icon-inactive.png +0 -0
  102. resources/assets/images/nav-icon-inactive@2x.png +0 -0
  103. resources/assets/images/placeholder-pixel.png +0 -0
  104. resources/assets/images/pro-bundle.png +0 -0
  105. resources/assets/images/shadow.png +0 -0
  106. resources/assets/images/shortcode-screenshot.jpg +0 -0
  107. resources/assets/images/welcome-screenshot.jpg +0 -0
  108. resources/assets/images/widget-screenshot.jpg +0 -0
  109. resources/assets/js/admin.js +2157 -0
  110. resources/assets/js/public.js +123 -0
  111. resources/backbone/tmpl-edit-slide-frame.php +9 -0
  112. backbone/edit-slide.php → resources/backbone/tmpl-edit-slide.php +23 -23
  113. resources/backbone/tmpl-slide.php +46 -0
  114. resources/views/edit-settings.php +36 -0
  115. resources/views/edit-slider.php +70 -0
  116. resources/views/edit-slider_sidebar.php +444 -0
  117. resources/views/list-sliders.php +40 -0
  118. resources/views/view-addons.php +88 -0
  119. src/Foundation/Activation/Activator.php +22 -0
  120. src/Foundation/Admin/Actions/Actions.php +50 -0
  121. src/Foundation/Admin/Actions/Processor.php +123 -0
  122. src/Foundation/Admin/Actions/ResourceActions.php +247 -0
  123. src/Foundation/Admin/Admin.php +99 -0
  124. src/Foundation/Admin/Ajax/Router.php +61 -0
  125. src/Foundation/Admin/Assets/Assets.php +17 -0
  126. src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php +216 -0
  127. src/Foundation/Admin/LicenseHandlers/LicenseHandler.php +154 -0
  128. src/Foundation/Admin/ListTables/ListTable.php +25 -0
  129. src/Foundation/Admin/Menus/Menu.php +232 -0
  130. src/Foundation/Admin/Notices/ErrorNotice.php +25 -0
  131. src/Foundation/Admin/Notices/InfoNotice.php +25 -0
  132. src/Foundation/Admin/Notices/Notice.php +75 -0
  133. src/Foundation/Admin/Notices/NoticeHandler.php +124 -0
  134. src/Foundation/Admin/Notices/SuccessNotice.php +25 -0
  135. src/Foundation/Admin/Panels/Panel.php +71 -0
  136. src/Foundation/Admin/Panels/Panels.php +121 -0
  137. src/Foundation/Admin/Panels/SettingsApiPanel.php +428 -0
  138. src/Foundation/Admin/PluginUpdaters/EDDPluginUpdater.php +65 -0
  139. src/Foundation/Admin/PluginUpdaters/PluginUpdater.php +192 -0
  140. src/Foundation/Admin/Upgrades/Upgrader.php +107 -0
  141. src/Foundation/Admin/Upgrades/Upgrades.php +74 -0
  142. src/Foundation/Admin/Validators/Validator.php +160 -0
  143. src/Foundation/Assets/Assets.php +33 -0
  144. src/Foundation/Capabilities/Capabilities.php +88 -0
  145. src/Foundation/Contracts/Activation/Activator.php +20 -0
  146. src/Foundation/Contracts/Admin/Actions/Actions.php +15 -0
  147. src/Foundation/Contracts/Admin/Actions/Processor.php +20 -0
  148. src/Foundation/Contracts/Admin/Actions/ResourceActions.php +61 -0
  149. src/Foundation/Contracts/Admin/Admin.php +15 -0
  150. src/Foundation/Contracts/Admin/Ajax/Router.php +23 -0
  151. src/Foundation/Contracts/Admin/Assets/Assets.php +17 -0
  152. src/Foundation/Contracts/Admin/LicenseHandlers/LicenseHandler.php +57 -0
  153. src/Foundation/Contracts/Admin/ListTables/ListTable.php +15 -0
  154. src/Foundation/Contracts/Admin/Menus/Menu.php +15 -0
  155. src/Foundation/Contracts/Admin/Notices/Notice.php +20 -0
  156. src/Foundation/Contracts/Admin/Notices/NoticeHandler.php +42 -0
  157. src/Foundation/Contracts/Admin/Panels/Panel.php +20 -0
  158. src/Foundation/Contracts/Admin/Panels/Panels.php +15 -0
  159. src/Foundation/Contracts/Admin/PluginUpdaters/.gitkeep +0 -0
  160. src/Foundation/Contracts/Admin/PluginUpdaters/PluginUpdater.php +15 -0
  161. src/Foundation/Contracts/Admin/Upgrades/Upgrader.php +20 -0
  162. src/Foundation/Contracts/Admin/Upgrades/Upgrades.php +15 -0
  163. src/Foundation/Contracts/Admin/Validators/Validator.php +21 -0
  164. src/Foundation/Contracts/Assets/Assets.php +20 -0
  165. src/Foundation/Contracts/Capabilities/Capabilities.php +27 -0
  166. src/Foundation/Contracts/Models/Model.php +45 -0
  167. src/Foundation/Contracts/Options/Option.php +49 -0
  168. src/Foundation/Contracts/Options/OptionArray.php +29 -0
  169. src/Foundation/Contracts/Plugin.php +15 -0
  170. src/Foundation/Contracts/Repositories/Repository.php +93 -0
  171. src/Foundation/Contracts/Shortcodes/Shortcode.php +28 -0
  172. src/Foundation/Contracts/TemplateLoaders/TemplateLoader.php +24 -0
  173. src/Foundation/Contracts/Uninstallation/Uninstaller.php +20 -0
  174. src/Foundation/Contracts/Widgets/Widget.php +15 -0
  175. src/Foundation/Models/Model.php +118 -0
  176. src/Foundation/Options/Option.php +99 -0
  177. src/Foundation/Options/OptionArray.php +61 -0
  178. src/Foundation/Plugin.php +105 -0
  179. src/Foundation/Repositories/PostType.php +462 -0
  180. src/Foundation/Shortcodes/Shortcode.php +60 -0
  181. src/Foundation/TemplateLoaders/TemplateLoader.php +157 -0
  182. src/Foundation/Uninstallation/Uninstaller.php +22 -0
  183. src/Foundation/Widgets/Widget.php +109 -0
  184. src/Foundation/helpers.php +127 -0
  185. src/Plugin/Activation/Activator.php +113 -0
  186. src/Plugin/Admin/Actions/Addons.php +138 -0
  187. src/Plugin/Admin/Actions/Processor.php +29 -0
  188. src/Plugin/Admin/Actions/Settings.php +87 -0
  189. src/Plugin/Admin/Actions/Sliders.php +79 -0
  190. src/Plugin/Admin/AddonUpdater.php +79 -0
  191. src/Plugin/Admin/Admin.php +133 -0
  192. src/Plugin/Admin/Ajax/AddonActivator.php +41 -0
  193. src/Plugin/Admin/Ajax/AddonDeactivator.php +36 -0
  194. src/Plugin/Admin/Ajax/AddonInstaller.php +84 -0
  195. src/Plugin/Admin/Ajax/Router.php +84 -0
  196. src/Plugin/Admin/Assets/Assets.php +148 -0
  197. src/Plugin/Admin/LicenseHandler.php +32 -0
  198. src/Plugin/Admin/ListTables/Sliders.php +533 -0
  199. src/Plugin/Admin/MediaButton.php +146 -0
  200. src/Plugin/Admin/Menus/Menu.php +131 -0
  201. src/Plugin/Admin/Panels/Addons.php +115 -0
  202. src/Plugin/Admin/Panels/AllSliders.php +80 -0
  203. src/Plugin/Admin/Panels/CreateSlider.php +26 -0
  204. src/Plugin/Admin/Panels/EditSlider.php +93 -0
  205. src/Plugin/Admin/Panels/ListSliders.php +77 -0
  206. src/Plugin/Admin/Panels/Panels.php +43 -0
  207. src/Plugin/Admin/Panels/Settings.php +136 -0
  208. src/Plugin/Admin/UpgraderSkin.php +103 -0
  209. src/Plugin/Admin/Upgrades/UpgradeTo300.php +318 -0
  210. src/Plugin/Admin/Upgrades/Upgrader.php +27 -0
  211. src/Plugin/Admin/Upgrades/Upgrades.php +25 -0
  212. src/Plugin/Admin/Validators/License.php +28 -0
  213. src/Plugin/Admin/Validators/Settings.php +28 -0
  214. src/Plugin/Admin/Validators/Slider.php +49 -0
  215. src/Plugin/Assets/PublicAssets.php +91 -0
  216. src/Plugin/Capabilities/Capabilities.php +32 -0
  217. src/Plugin/Contracts/Admin/Validators/License.php +17 -0
  218. src/Plugin/Contracts/Admin/Validators/Settings.php +17 -0
  219. src/Plugin/Contracts/Admin/Validators/Slider.php +17 -0
  220. src/Plugin/Contracts/Options/License.php +22 -0
  221. src/Plugin/Contracts/Options/Settings.php +17 -0
  222. src/Plugin/Contracts/Options/UpgradeLicense.php +0 -0
  223. src/Plugin/Contracts/Options/Version.php +17 -0
  224. src/Plugin/Models/Slider.php +47 -0
  225. src/Plugin/Options/License.php +54 -0
  226. src/Plugin/Options/Settings.php +36 -0
  227. src/Plugin/Options/UpgradeLicense.php +32 -0
  228. src/Plugin/Options/Version.php +33 -0
  229. src/Plugin/Plugin.php +188 -0
  230. src/Plugin/Repositories/Sliders.php +50 -0
  231. src/Plugin/Shortcodes/Slider.php +89 -0
  232. src/Plugin/Support/AttachmentImageResizer.php +168 -0
  233. src/Plugin/TemplateLoaders/TemplateLoader.php +25 -0
  234. src/Plugin/Uninstallation/Uninstaller.php +164 -0
  235. src/Plugin/Views/Slider.php +60 -0
  236. src/Plugin/Widgets/Slider.php +127 -0
  237. src/Plugin/helpers.php +530 -0
  238. templates/slider.php +11 -0
  239. uninstall.php +21 -0
  240. vendor/autoload.php +7 -0
  241. vendor/composer/ClassLoader.php +413 -0
  242. vendor/composer/LICENSE +21 -0
  243. vendor/composer/autoload_classmap.php +9 -0
  244. vendor/composer/autoload_files.php +11 -0
  245. vendor/composer/autoload_namespaces.php +10 -0
  246. vendor/composer/autoload_psr4.php +11 -0
  247. vendor/composer/autoload_real.php +59 -0
  248. vendor/composer/installed.json +166 -0
  249. vendor/rdlowrey/auryn/.gitignore +3 -0
  250. vendor/rdlowrey/auryn/.php_cs +15 -0
  251. vendor/rdlowrey/auryn/.travis.yml +14 -0
  252. vendor/rdlowrey/auryn/CONTRIBUTING.md +28 -0
  253. vendor/rdlowrey/auryn/LICENSE +21 -0
  254. vendor/rdlowrey/auryn/README.md +847 -0
  255. vendor/rdlowrey/auryn/composer.json +46 -0
  256. vendor/rdlowrey/auryn/lib/CachingReflector.php +132 -0
  257. vendor/rdlowrey/auryn/lib/ConfigException.php +7 -0
  258. vendor/rdlowrey/auryn/lib/Executable.php +82 -0
  259. vendor/rdlowrey/auryn/lib/InjectionException.php +67 -0
  260. vendor/rdlowrey/auryn/lib/Injector.php +738 -0
  261. vendor/rdlowrey/auryn/lib/InjectorException.php +7 -0
  262. vendor/rdlowrey/auryn/lib/ReflectionCache.php +9 -0
  263. vendor/rdlowrey/auryn/lib/ReflectionCacheApc.php +41 -0
  264. vendor/rdlowrey/auryn/lib/ReflectionCacheArray.php +22 -0
  265. vendor/rdlowrey/auryn/lib/Reflector.php +61 -0
  266. vendor/rdlowrey/auryn/lib/StandardReflector.php +46 -0
  267. vendor/rdlowrey/auryn/phpunit.xml +43 -0
  268. vendor/rdlowrey/auryn/test/Benchmark/ExecuteBenchmark.php +63 -0
  269. vendor/rdlowrey/auryn/test/Benchmark/Noop.php +21 -0
  270. vendor/rdlowrey/auryn/test/InjectorTest.php +201 -0
.bowerrc ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ {
2
+ "directory": "resources/assets/bower_components"
3
+ }
Gruntfile.js ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = function(grunt) {
2
+ grunt.initConfig({
3
+ pkg: grunt.file.readJSON('package.json'),
4
+ concat: {
5
+ css: {
6
+ files: {
7
+ 'assets/css/admin.css': [
8
+ 'resources/assets/css/admin.css'
9
+ ],
10
+ 'assets/css/public.css': [
11
+ 'resources/assets/bower_components/owlcarousel/owl-carousel/owl.carousel.css',
12
+ 'resources/assets/bower_components/owlcarousel/owl-carousel/owl.transitions.css',
13
+ 'resources/assets/css/public.css'
14
+ ]
15
+ }
16
+ },
17
+ js: {
18
+ files: {
19
+ 'assets/js/admin.js': [
20
+ 'resources/assets/js/admin.js'
21
+ ],
22
+ 'assets/js/public.js': [
23
+ 'resources/assets/bower_components/owlcarousel/owl-carousel/owl.carousel.js',
24
+ 'resources/assets/js/public.js'
25
+ ]
26
+ }
27
+ }
28
+ },
29
+ copy: {
30
+ images: {
31
+ files: [{
32
+ expand: true,
33
+ flatten: true,
34
+ src: ['resources/assets/images/*'],
35
+ dest: 'assets/images'
36
+ }]
37
+ }
38
+ },
39
+ cssmin: {
40
+ main: {
41
+ files: {
42
+ 'assets/css/admin.min.css': [
43
+ 'assets/css/admin.css'
44
+ ],
45
+ 'assets/css/public.min.css': [
46
+ 'assets/css/public.css'
47
+ ]
48
+ }
49
+ },
50
+ },
51
+ makepot: {
52
+ target: {
53
+ options: {
54
+ include: [
55
+ 'src/.*'
56
+ ],
57
+ type: 'wp-plugin'
58
+ }
59
+ }
60
+ },
61
+ replace: {
62
+ js: {
63
+ files: {
64
+ 'assets/js/public.js': [
65
+ 'assets/js/public.js'
66
+ ],
67
+ 'assets/js/public.min.js': [
68
+ 'assets/js/public.min.js'
69
+ ]
70
+ },
71
+ options: {
72
+ patterns: [{
73
+ match: 'owlCarousel',
74
+ replacement: 'easingSlider'
75
+ }, {
76
+ match: 'owl-carousel',
77
+ replacement: 'easingslider'
78
+ }, {
79
+ match: 'lazyOwl',
80
+ replacement: 'easingslider-lazy'
81
+ }, {
82
+ match: 'owl',
83
+ replacement: 'easingslider'
84
+ }],
85
+ usePrefix: false
86
+ }
87
+ },
88
+ css: {
89
+ files: {
90
+ 'assets/css/public.css': [
91
+ 'assets/css/public.css'
92
+ ],
93
+ 'assets/css/public.min.css': [
94
+ 'assets/css/public.min.css'
95
+ ],
96
+ },
97
+ options: {
98
+ patterns: [{
99
+ match: 'owl-carousel',
100
+ replacement: 'easingslider-container'
101
+ }, {
102
+ match: 'owl',
103
+ replacement: 'easingslider'
104
+ }],
105
+ usePrefix: false
106
+ }
107
+ },
108
+ },
109
+ uglify: {
110
+ main: {
111
+ files: {
112
+ 'assets/js/admin.min.js': [
113
+ 'assets/js/admin.js'
114
+ ],
115
+ 'assets/js/public.min.js': [
116
+ 'assets/js/public.js'
117
+ ]
118
+ }
119
+ }
120
+ },
121
+ watch: {
122
+ js: {
123
+ files: [
124
+ 'resources/assets/js/*.js'
125
+ ],
126
+ tasks: ['js']
127
+ },
128
+ css: {
129
+ files: [
130
+ 'resources/assets/css/*.css'
131
+ ],
132
+ tasks: ['css']
133
+ }
134
+ }
135
+ });
136
+
137
+ grunt.loadNpmTasks('grunt-contrib-concat');
138
+ grunt.loadNpmTasks('grunt-contrib-copy');
139
+ grunt.loadNpmTasks('grunt-contrib-cssmin');
140
+ grunt.loadNpmTasks('grunt-contrib-uglify');
141
+ grunt.loadNpmTasks('grunt-contrib-watch');
142
+ grunt.loadNpmTasks('grunt-replace');
143
+ grunt.loadNpmTasks('grunt-wp-i18n');
144
+
145
+ grunt.registerTask('js', ['concat:js', 'uglify:main', 'replace:js']);
146
+ grunt.registerTask('css', ['concat:css', 'cssmin:main', 'replace:css']);
147
+ grunt.registerTask('default', ['makepot', 'css', 'js', 'copy']);
148
+ };
css/editor-pages.css → assets/css/admin.css RENAMED
@@ -1,3 +1,5 @@
 
 
1
  .clearfix {
2
  *zoom: 1;
3
  }
@@ -12,22 +14,72 @@
12
  clear: both;
13
  }
14
 
 
 
 
 
15
  .updated.notice {
16
  border-color: #ffba00 !important;
17
  }
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  .wp-list-table .column-ID {
20
  width: 4em;
21
  }
22
 
23
- .thumbnail .action .details-url {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  width: 100%;
25
- max-width: 700px;
26
  }
27
 
28
- .image-details .media-modal {
29
- left: 30px !important;
30
- right: 30px !important;
31
  }
32
 
33
  .attachment-info .settings {
@@ -68,36 +120,143 @@
68
  padding-top: 0;
69
  }
70
 
71
- .description {
72
- font-size: 11px !important;
73
- font-style: italic !important;
74
- display: block !important;
75
- color: #777 !important;
76
- padding: 5px 0 !important;
77
  }
78
 
79
- .media-modal .description {
80
  margin-top: 10px !important;
81
  }
82
 
83
- .media-modal .media-embed .thumbnail {
84
  max-height: none;
85
  max-width: none;
86
  }
87
 
88
- .media-modal .media-embed .thumbnail img {
89
  max-height: none;
90
  max-width: 1000px;
91
  width: 100%;
92
  }
93
 
94
- .list {
95
- margin: 0 0 20px 20px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  }
97
 
98
- .list li {
99
- font-size: 11px !important;
100
- color: #777 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  }
102
 
103
  .toolbar-container .media-toolbar {
@@ -121,6 +280,10 @@
121
  text-align: right;
122
  }
123
 
 
 
 
 
124
  .toolbar-container .media-toolbar .media-button {
125
  margin-top: 10px;
126
  margin-bottom: 10px;
@@ -178,7 +341,7 @@
178
  float: left;
179
  }
180
 
181
- .settings-container {
182
  float: right;
183
  margin-right: -300px;
184
  width: 280px;
@@ -204,6 +367,7 @@
204
 
205
  .settings-container .sidebar-name-arrow:before {
206
  top: 4px !important;
 
207
  }
208
 
209
  .settings-container.closed .sidebar-name {
@@ -241,6 +405,10 @@
241
  float: left;
242
  }
243
 
 
 
 
 
244
  .settings-container .sidebar-content .field select,
245
  .settings-container .sidebar-content .field input[type="text"],
246
  .settings-container .sidebar-content .field input[type="number"] {
@@ -269,10 +437,6 @@
269
  margin-right: 2px;
270
  }
271
 
272
- .settings-container .sidebar-content .advanced-options.hidden {
273
- display: none !important;
274
- }
275
-
276
  .settings-container .sidebar-content .show-advanced-options {
277
  margin: 15px 0;
278
  font-weight: bold;
@@ -292,12 +456,16 @@
292
  padding-right: 0;
293
  }
294
 
295
- .settings-container .dimension-settings .field.half {
296
- width: 45%;
 
 
297
  }
298
 
299
- .settings-container .dimension-settings .field.half:first-child {
300
- margin-right: 5%;
 
 
301
  }
302
 
303
  #slides-browser .ui-sortable {
@@ -371,6 +539,158 @@
371
  opacity: 1;
372
  }
373
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
  @media only screen and (max-width: 1040px) {
375
  .toolbar-container .media-toolbar .media-toolbar-primary,
376
  .toolbar-container .media-toolbar .media-toolbar-secondary {
@@ -390,16 +710,29 @@
390
  }
391
  }
392
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  @media only screen and (max-width: 640px) {
394
- .image-details .media-modal {
395
  left: 0 !important;
396
  right: 0 !important;
397
  }
398
 
399
- .image-details .media-modal select,
400
- .image-details .media-modal textarea,
401
- .image-details .media-modal input[type="url"],
402
- .image-details .media-modal input[type="text"] {
403
  font-size: 16px;
404
  padding: 6px 10px;
405
  }
@@ -455,4 +788,4 @@
455
  margin-right: 0;
456
  width: 100%;
457
  }
458
- }
1
+ /* Global
2
+ -------------------------------------------------------------- */
3
  .clearfix {
4
  *zoom: 1;
5
  }
14
  clear: both;
15
  }
16
 
17
+ .hide {
18
+ display: none !important;
19
+ }
20
+
21
  .updated.notice {
22
  border-color: #ffba00 !important;
23
  }
24
 
25
+ .message.is-dismissable {
26
+ position: relative;
27
+ }
28
+
29
+ .field.half {
30
+ width: 45% !important;
31
+ }
32
+
33
+ .field.half:first-child {
34
+ margin-right: 5% !important;
35
+ }
36
+
37
+ .description {
38
+ font-size: 11px !important;
39
+ font-style: italic !important;
40
+ display: block !important;
41
+ color: #777 !important;
42
+ padding: 5px 0 !important;
43
+ }
44
+
45
+ .thumbnail-dashicon {
46
+ font-size: 15px;
47
+ height: 15px;
48
+ width: 15px;
49
+ margin-top: 1px;
50
+ margin-right: 2px;
51
+ }
52
+
53
+ /* Slider Editor
54
+ -------------------------------------------------------------- */
55
  .wp-list-table .column-ID {
56
  width: 4em;
57
  }
58
 
59
+ .wp-list-table .column-post_title {
60
+ width: 35%;
61
+ }
62
+
63
+ .wp-list-table .column-template_function {
64
+ white-space: nowrap;
65
+ overflow: hidden;
66
+ text-overflow: ellipsis;
67
+ }
68
+
69
+ .wp-list-table td.post_title strong {
70
+ display: block;
71
+ margin-bottom: 0.2em;
72
+ font-size: 14px;
73
+ }
74
+
75
+ .wp-list-table .column-shortcode input[type="text"],
76
+ .wp-list-table .column-template_function input[type="text"] {
77
  width: 100%;
 
78
  }
79
 
80
+ .thumbnail .action .details-url {
81
+ width: 100%;
82
+ max-width: 700px;
83
  }
84
 
85
  .attachment-info .settings {
120
  padding-top: 0;
121
  }
122
 
123
+ .edit-slide-frame select.attachment-filters {
124
+ max-width: 95%;
 
 
 
 
125
  }
126
 
127
+ .edit-slide-frame .description {
128
  margin-top: 10px !important;
129
  }
130
 
131
+ .edit-slide-frame .media-embed .thumbnail {
132
  max-height: none;
133
  max-width: none;
134
  }
135
 
136
+ .edit-slide-frame .media-embed .thumbnail img {
137
  max-height: none;
138
  max-width: 1000px;
139
  width: 100%;
140
  }
141
 
142
+ .media-modal .media-modal-close,
143
+ .edit-slide-frame .edit-media-header .left,
144
+ .edit-slide-frame .edit-media-header .right {
145
+ -webkit-transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
146
+ -moz-transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
147
+ -ms-transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
148
+ -o-transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
149
+ transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
150
+ cursor: pointer;
151
+ color: #777;
152
+ background-color: transparent;
153
+ height: 50px;
154
+ width: 50px;
155
+ padding: 0;
156
+ position: absolute;
157
+ text-align: center;
158
+ border: 0;
159
+ border-left: 1px solid #ddd;
160
  }
161
 
162
+ .media-modal .media-modal-close {
163
+ top: 0;
164
+ right: 0;
165
+ }
166
+
167
+ .media-modal .media-modal-close.no-border,
168
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close {
169
+ border-width: 0;
170
+ }
171
+
172
+ .media-modal .media-modal-close.no-border:focus,
173
+ .media-modal .media-modal-close.no-border:hover,
174
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close:focus,
175
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close:hover {
176
+ background: transparent;
177
+ }
178
+
179
+ .media-modal .media-modal-close.no-border:focus .media-modal-icon:before,
180
+ .media-modal .media-modal-close.no-border:hover .media-modal-icon:before,
181
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close:focus .media-modal-icon:before,
182
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close:hover .media-modal-icon:before {
183
+ color: #0073aa;
184
+ }
185
+
186
+ .media-modal .media-modal-close .media-modal-icon:before {
187
+ content: '\f335';
188
+ font-size: 22px;
189
+ }
190
+
191
+ .media-modal .media-modal-close .media-modal-icon {
192
+ margin: 14px;
193
+ width: 22px;
194
+ }
195
+
196
+ .edit-slide-frame .edit-media-header .left {
197
+ right: 102px;
198
+ }
199
+
200
+ .edit-slide-frame .edit-media-header .right {
201
+ right: 51px;
202
+ }
203
+
204
+ .edit-slide-frame .edit-media-header .right:before,
205
+ .edit-slide-frame .edit-media-header .left:before {
206
+ font: normal 20px/50px 'dashicons' !important;
207
+ display: inline;
208
+ font-weight: 300;
209
+ }
210
+
211
+ .media-modal .media-modal-close:hover,
212
+ .media-modal .media-modal-close:focus,
213
+ .edit-slide-frame .edit-media-header .left:hover,
214
+ .edit-slide-frame .edit-media-header .right:hover,
215
+ .edit-slide-frame .edit-media-header .left:focus,
216
+ .edit-slide-frame .edit-media-header .right:focus {
217
+ background: #ddd;
218
+ border-color: #ccc;
219
+ color: #000;
220
+ outline: none;
221
+ }
222
+
223
+ .media-modal .media-modal-close:focus .media-modal-icon:before,
224
+ .media-modal .media-modal-close:hover .media-modal-icon:before {
225
+ color: #000;
226
+ }
227
+
228
+ .edit-slide-frame .edit-media-header .left:before,
229
+ .rtl .edit-slide-frame .edit-media-header .right:before {
230
+ content: '\f341';
231
+ }
232
+
233
+ .edit-slide-frame .edit-media-header .right:before,
234
+ .rtl .edit-slide-frame .edit-media-header .left:before {
235
+ content: '\f345';
236
+ }
237
+
238
+ .edit-slide-frame .edit-media-header .left.disabled,
239
+ .edit-slide-frame .edit-media-header .right.disabled,
240
+ .edit-slide-frame .edit-media-header .left.disabled:hover,
241
+ .edit-slide-frame .edit-media-header .right.disabled:hover {
242
+ color: #ccc;
243
+ background: inherit;
244
+ cursor: default;
245
+ pointer-events: none;
246
+ }
247
+
248
+ .edit-slide-frame .media-frame-title {
249
+ -webkit-box-shadow: none !important;
250
+ -moz-box-shadow: none !important;
251
+ box-shadow: none !important;
252
+ left: 0;
253
+ right: 150px; /* leave space for prev/next/close */
254
+ }
255
+
256
+ .edit-slide-frame .media-frame-content {
257
+ -webkit-box-shadow: inset 0px 4px 4px -4px rgba(0, 0, 0, 0.1);
258
+ -moz-box-shadow: inset 0px 4px 4px -4px rgba(0, 0, 0, 0.1);
259
+ box-shadow: inset 0px 4px 4px -4px rgba(0, 0, 0, 0.1);
260
  }
261
 
262
  .toolbar-container .media-toolbar {
280
  text-align: right;
281
  }
282
 
283
+ .toolbar-container .media-toolbar .media-toolbar-secondary {
284
+ margin-bottom: 9px;
285
+ }
286
+
287
  .toolbar-container .media-toolbar .media-button {
288
  margin-top: 10px;
289
  margin-bottom: 10px;
341
  float: left;
342
  }
343
 
344
+ .sidebar-container {
345
  float: right;
346
  margin-right: -300px;
347
  width: 280px;
367
 
368
  .settings-container .sidebar-name-arrow:before {
369
  top: 4px !important;
370
+ padding: 14px !important;
371
  }
372
 
373
  .settings-container.closed .sidebar-name {
405
  float: left;
406
  }
407
 
408
+ .settings-container .sidebar-content .field-extra {
409
+ margin-top: 0;
410
+ }
411
+
412
  .settings-container .sidebar-content .field select,
413
  .settings-container .sidebar-content .field input[type="text"],
414
  .settings-container .sidebar-content .field input[type="number"] {
437
  margin-right: 2px;
438
  }
439
 
 
 
 
 
440
  .settings-container .sidebar-content .show-advanced-options {
441
  margin: 15px 0;
442
  font-weight: bold;
456
  padding-right: 0;
457
  }
458
 
459
+ .settings-container #major-publishing-actions .submitdelete {
460
+ text-decoration: none;
461
+ padding: 1px 2px;
462
+ color: #a00;
463
  }
464
 
465
+ .settings-container #major-publishing-actions .submitdelete:hover {
466
+ color: #f00;
467
+ text-decoration: none;
468
+ border: none;
469
  }
470
 
471
  #slides-browser .ui-sortable {
539
  opacity: 1;
540
  }
541
 
542
+ /* Settings
543
+ -------------------------------------------------------------- */
544
+ .form-table label span {
545
+ margin-right: 15px;
546
+ }
547
+
548
+ .valid-license {
549
+ position: relative;
550
+ }
551
+
552
+ .valid-license:after {
553
+ content: "\f147";
554
+ font-family: "Dashicons";
555
+ position: absolute;
556
+ top: 0;
557
+ bottom: 0;
558
+ right: 10px;
559
+ color: #468847;
560
+ font-size: 18px;
561
+ }
562
+
563
+ /* License Entry
564
+ -------------------------------------------------------------- */
565
+ .license-entry {
566
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);
567
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);
568
+ border-left: 4px solid #fff;
569
+ background: #fff;
570
+ padding: 16px 10px;
571
+ margin-bottom: 15px;
572
+ }
573
+
574
+ .license-entry.license-required {
575
+ border-left-color: #ffba00;
576
+ }
577
+
578
+ .license-entry.license-valid {
579
+ border-left-color: #46b450;
580
+ }
581
+
582
+ .license-entry p {
583
+ margin-top: 0 !important;
584
+ }
585
+
586
+ .license-entry #license-key {
587
+ min-width: 300px;
588
+ margin-right: 5px;
589
+ }
590
+
591
+ .license-entry #masked-key {
592
+ line-height: 28px;
593
+ margin-right: 5px;
594
+ }
595
+
596
+ /* Addons
597
+ -------------------------------------------------------------- */
598
+ .addon {
599
+ background: #fff;
600
+ border: 1px solid #ccc;
601
+ margin: 0 20px 20px 0;
602
+ padding: 15px;
603
+ float: left;
604
+ width: 300px;
605
+ height: 410px;
606
+ position: relative;
607
+ }
608
+
609
+ .addon .addon-thumbnail {
610
+ display: block;
611
+ }
612
+
613
+ .addon .addon-thumbnail img {
614
+ max-width: 100%;
615
+ }
616
+
617
+ .addon .action-error {
618
+ line-height: 28px;
619
+ margin: 10px 0;
620
+ display: block;
621
+ }
622
+
623
+ .addon .addon-action {
624
+ display: block;
625
+ /*margin: -16px -16px 15px -16px;*/
626
+ }
627
+
628
+ .addon .addon-image {
629
+ max-width: 100%;
630
+ height: auto;
631
+ }
632
+
633
+ .addon .addon-status {
634
+ position: absolute;
635
+ bottom: 15px;
636
+ left: 15px;
637
+ right: 15px;
638
+ padding: 6px 10px;
639
+ background: #eaeaea;
640
+ border-width: 1px;
641
+ border-style: solid;
642
+ border-color: #dadada;
643
+ }
644
+
645
+ .addon .addon-status.no-license {
646
+ color: #a94442;
647
+ background: #f2dede;
648
+ border-color: #dca7a7;
649
+ }
650
+
651
+ .addon .addon-status.upgrade-license {
652
+ color: #8a6d3b;
653
+ background: #fcf8e3;
654
+ border-color: #f5e79e;
655
+ }
656
+
657
+ .addon .addon-status.is-inactive {
658
+ color: #31708f;
659
+ background: #d9edf7;
660
+ border-color: #9acfea;
661
+ }
662
+
663
+ .addon .addon-status.is-active {
664
+ color: #3c763d;
665
+ background: #dff0d8;
666
+ border-color: #b2dba1;
667
+ }
668
+
669
+ .addon .addon-status span {
670
+ line-height: 28px;
671
+ }
672
+
673
+ .addon .addon-status .button-primary {
674
+ float: right;
675
+ }
676
+
677
+ .addon .addon-status .upgrade-link {
678
+ display: block;
679
+ }
680
+
681
+ /* Upgrade Info
682
+ -------------------------------------------------------------- */
683
+ .upgrade-info .upgrade-info-title {
684
+ font-size: 24px;
685
+ }
686
+
687
+ .upgrade-info .upgrade-info-list li {
688
+ display: inline-block;
689
+ margin-right: 20px;
690
+ }
691
+
692
+ /* Media Queries
693
+ -------------------------------------------------------------- */
694
  @media only screen and (max-width: 1040px) {
695
  .toolbar-container .media-toolbar .media-toolbar-primary,
696
  .toolbar-container .media-toolbar .media-toolbar-secondary {
710
  }
711
  }
712
 
713
+ @media only screen and (max-width: 782px) {
714
+ .wp-list-table .column-post_title {
715
+ width: 75%;
716
+ }
717
+
718
+ .wp-list-table .column-post_author,
719
+ .wp-list-table .column-post_date,
720
+ .wp-list-table .column-shortcode,
721
+ .wp-list-table .column-template_function {
722
+ display: none;
723
+ }
724
+ }
725
+
726
  @media only screen and (max-width: 640px) {
727
+ .media-modal {
728
  left: 0 !important;
729
  right: 0 !important;
730
  }
731
 
732
+ .media-modal select,
733
+ .media-modal textarea,
734
+ .media-modal input[type="url"],
735
+ .media-modal input[type="text"] {
736
  font-size: 16px;
737
  padding: 6px 10px;
738
  }
788
  margin-right: 0;
789
  width: 100%;
790
  }
791
+ }
assets/css/admin.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .clearfix::after,.clearfix::before{display:table;content:'';line-height:0}.clearfix::after{clear:both}.hide{display:none!important}.updated.notice{border-color:#ffba00!important}.message.is-dismissable{position:relative}.field.half{width:45%!important}.field.half:first-child{margin-right:5%!important}.description{font-size:11px!important;font-style:italic!important;display:block!important;color:#777!important;padding:5px 0!important}.thumbnail-dashicon{font-size:15px;height:15px;width:15px;margin-top:1px;margin-right:2px}.wp-list-table .column-ID{width:4em}.wp-list-table .column-post_title{width:35%}.wp-list-table .column-template_function{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wp-list-table td.post_title strong{display:block;margin-bottom:.2em;font-size:14px}.wp-list-table .column-shortcode input[type=text],.wp-list-table .column-template_function input[type=text]{width:100%}.thumbnail .action .details-url{width:100%;max-width:700px}.attachment-info .settings{border-bottom-width:0!important}.attachment-info .settings h3{margin:10px 0;position:relative;font-weight:700;text-transform:uppercase;font-size:12px;color:#666}.attachment-info .setting .link-options{width:65%;float:right;margin:1px}.attachment-info .setting .link-options input[type=text]{width:98%;float:none;margin:5px 0 0}.attachment-info .setting .link-options label{margin-top:5px}.attachment-info .setting .link-options input[type=checkbox]{margin:-1px 5px 0 0!important}.attachment-info .column-settings h3.no-border{border-top-width:0;padding-top:0}.edit-slide-frame select.attachment-filters{max-width:95%}.edit-slide-frame .description{margin-top:10px!important}.edit-slide-frame .media-embed .thumbnail{max-height:none;max-width:none}.edit-slide-frame .media-embed .thumbnail img{max-height:none;max-width:1000px;width:100%}.edit-slide-frame .edit-media-header .left,.edit-slide-frame .edit-media-header .right,.media-modal .media-modal-close{-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;-moz-transition:color .1s ease-in-out,background .1s ease-in-out;-ms-transition:color .1s ease-in-out,background .1s ease-in-out;-o-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out;cursor:pointer;color:#777;background-color:transparent;height:50px;width:50px;padding:0;position:absolute;text-align:center;border:0;border-left:1px solid #ddd}.media-modal .media-modal-close{top:0;right:0}.media-modal .media-modal-close.no-border,div[id*="__wp-uploader-id"] .media-modal .media-modal-close{border-width:0}.media-modal .media-modal-close.no-border:focus,.media-modal .media-modal-close.no-border:hover,div[id*="__wp-uploader-id"] .media-modal .media-modal-close:focus,div[id*="__wp-uploader-id"] .media-modal .media-modal-close:hover{background:0 0}.media-modal .media-modal-close.no-border:focus .media-modal-icon:before,.media-modal .media-modal-close.no-border:hover .media-modal-icon:before,div[id*="__wp-uploader-id"] .media-modal .media-modal-close:focus .media-modal-icon:before,div[id*="__wp-uploader-id"] .media-modal .media-modal-close:hover .media-modal-icon:before{color:#0073aa}.media-modal .media-modal-close .media-modal-icon:before{content:'\f335';font-size:22px}.media-modal .media-modal-close .media-modal-icon{margin:14px;width:22px}.edit-slide-frame .edit-media-header .left{right:102px}.edit-slide-frame .edit-media-header .right{right:51px}.edit-slide-frame .edit-media-header .left:before,.edit-slide-frame .edit-media-header .right:before{font:400 20px/50px dashicons!important;display:inline;font-weight:300}.edit-slide-frame .edit-media-header .left:focus,.edit-slide-frame .edit-media-header .left:hover,.edit-slide-frame .edit-media-header .right:focus,.edit-slide-frame .edit-media-header .right:hover,.media-modal .media-modal-close:focus,.media-modal .media-modal-close:hover{background:#ddd;border-color:#ccc;color:#000;outline:0}.media-modal .media-modal-close:focus .media-modal-icon:before,.media-modal .media-modal-close:hover .media-modal-icon:before{color:#000}.edit-slide-frame .edit-media-header .left:before,.rtl .edit-slide-frame .edit-media-header .right:before{content:'\f341'}.edit-slide-frame .edit-media-header .right:before,.rtl .edit-slide-frame .edit-media-header .left:before{content:'\f345'}.edit-slide-frame .edit-media-header .left.disabled,.edit-slide-frame .edit-media-header .left.disabled:hover,.edit-slide-frame .edit-media-header .right.disabled,.edit-slide-frame .edit-media-header .right.disabled:hover{color:#ccc;background:inherit;cursor:default;pointer-events:none}.edit-slide-frame .media-frame-title{-webkit-box-shadow:none!important;-moz-box-shadow:none!important;box-shadow:none!important;left:0;right:150px}.edit-slide-frame .media-frame-content{-webkit-box-shadow:inset 0 4px 4px -4px rgba(0,0,0,.1);-moz-box-shadow:inset 0 4px 4px -4px rgba(0,0,0,.1);box-shadow:inset 0 4px 4px -4px rgba(0,0,0,.1)}.toolbar-container .media-toolbar{-webkit-box-shadow:0 1px 1px rgba(0,0,0,.04);-moz-box-shadow:0 1px 1px rgba(0,0,0,.04);box-shadow:0 1px 1px rgba(0,0,0,.04);border:1px solid #e5e5e5;margin-top:10px;margin-bottom:15px;position:relative;height:auto}.toolbar-container .media-toolbar .media-toolbar-primary,.toolbar-container .media-toolbar .media-toolbar-secondary{max-width:50%;min-width:384px}.toolbar-container .media-toolbar .media-toolbar-primary{text-align:right}.toolbar-container .media-toolbar .media-toolbar-secondary{margin-bottom:9px}.toolbar-container .media-toolbar .media-button,.toolbar-container .media-toolbar .randomize{float:none;margin-top:10px;margin-bottom:10px}.toolbar-container .media-toolbar .randomize{line-height:30px;display:inline-block}.toolbar-container .media-toolbar .randomize input[type=checkbox]{margin-top:-2px;margin-right:8px}.toolbar-container .title-form{float:left;margin-top:9px}.toolbar-container .title-form .media-button{margin-top:1px;margin-left:0}.toolbar-container .title-form label{vertical-align:top;font-weight:700;line-height:32px;margin:0 5px 0 0}.toolbar-container .title-form input[type=text]{margin:0;padding:3px 5px;width:280px;font-size:16px;font-weight:300;line-height:1.5}.main-container{margin-right:300px}.slides-container{width:100%;float:left}.sidebar-container{float:right;margin-right:-300px;width:280px}.settings-container .banners a{display:block;margin-bottom:15px}.settings-container .widgets-holder-wrap{margin-top:0;margin-bottom:10px}.settings-container .sidebar-name{border-bottom:1px solid #eee}.settings-container .sidebar-name h3{padding:15px}.settings-container .sidebar-name-arrow:before{top:4px!important;padding:14px!important}.settings-container.closed .sidebar-name{border-width:0}.settings-container .sidebar-content{border-width:0 1px 1px;border-style:none solid solid;border-color:#fff;-webkit-border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;padding:10px 15px;min-height:20px}.settings-container .sidebar-content .divider{margin-bottom:0}.settings-container .sidebar-content .field,.settings-container .sidebar-content .radio{width:100%;margin:1em 0}.settings-container .sidebar-content .field span{font-weight:700;display:block}.settings-container .sidebar-content .field{float:left}.settings-container .sidebar-content .field-extra{margin-top:0}.settings-container .sidebar-content .field input[type=text],.settings-container .sidebar-content .field input[type=number],.settings-container .sidebar-content .field select{width:90%}.settings-container .sidebar-content .field input[type=checkbox]{margin-right:4px}.settings-container .sidebar-content .radio>span{font-weight:700;float:left}.settings-container .sidebar-content .radio .buttons{float:right}.settings-container .sidebar-content .radio .buttons label{margin-right:10px}.settings-container .sidebar-content .radio .buttons input{margin-top:0;margin-right:2px}.settings-container .sidebar-content .show-advanced-options{margin:15px 0;font-weight:700;display:block}.settings-container .sidebar-content .manage-slides-buttons .dashicons-plus{line-height:28px}.settings-container .sidebar-content .manage-slides-buttons .dashicons-trash{line-height:27px}.settings-container .sidebar-content .misc-pub-section{padding-left:0;padding-right:0}.settings-container #major-publishing-actions .submitdelete{text-decoration:none;padding:1px 2px;color:#a00}.settings-container #major-publishing-actions .submitdelete:hover{color:red;text-decoration:none;border:none}#slides-browser .ui-sortable{min-height:300px}#slides-browser .spinner{float:left;display:inline}#slides-browser .attachment .toolbar{display:none;text-align:left;position:absolute;top:0;left:0}#slides-browser .attachment:hover .toolbar,.addon .addon-action,.addon .addon-status .upgrade-link,.addon .addon-thumbnail{display:block}#slides-browser .attachment .toolbar i{-webkit-box-shadow:0 1px 3px rgba(0,0,0,.5);-moz-box-shadow:0 1px 3px rgba(0,0,0,.5);box-shadow:0 1px 3px rgba(0,0,0,.5);position:relative;margin-top:7px;margin-left:7px;padding:2px;font-size:30px;height:30px;width:30px;background:#000;background:rgba(0,0,0,.9);cursor:pointer;z-index:9999;color:#fff}#slides-browser .attachment .toolbar i:hover{-webkit-box-shadow:0 1px 3px rgba(0,0,0,.8);-moz-box-shadow:0 1px 3px rgba(0,0,0,.8);box-shadow:0 1px 3px rgba(0,0,0,.8);background-color:#000;color:#2ea2cc}#slides-browser .attachment .check div{background-position:21px 0}#slides-browser .attachment.selected .check div{background-position:-21px 0}#slides-browser .attachment.selected .check:hover div{background-position:-60px 0}#slides-browser .thumbnail img{width:100%}#slides-browser .thumbnail img.icon{width:auto}#slides-browser .thumbnail:hover .delete-button{opacity:1}.form-table label span{margin-right:15px}.valid-license{position:relative}.valid-license:after{content:"\f147";font-family:Dashicons;position:absolute;top:0;bottom:0;right:10px;color:#468847;font-size:18px}.license-entry{-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);border-left:4px solid #fff;background:#fff;padding:16px 10px;margin-bottom:15px}.license-entry.license-required{border-left-color:#ffba00}.license-entry.license-valid{border-left-color:#46b450}.license-entry p{margin-top:0!important}.license-entry #license-key{min-width:300px;margin-right:5px}.license-entry #masked-key{line-height:28px;margin-right:5px}.addon{background:#fff;border:1px solid #ccc;margin:0 20px 20px 0;padding:15px;float:left;width:300px;height:410px;position:relative}.addon .addon-thumbnail img{max-width:100%}.addon .action-error{line-height:28px;margin:10px 0;display:block}.addon .addon-image{max-width:100%;height:auto}.addon .addon-status{position:absolute;bottom:15px;left:15px;right:15px;padding:6px 10px;background:#eaeaea;border-width:1px;border-style:solid;border-color:#dadada}.addon .addon-status.no-license{color:#a94442;background:#f2dede;border-color:#dca7a7}.addon .addon-status.upgrade-license{color:#8a6d3b;background:#fcf8e3;border-color:#f5e79e}.addon .addon-status.is-inactive{color:#31708f;background:#d9edf7;border-color:#9acfea}.addon .addon-status.is-active{color:#3c763d;background:#dff0d8;border-color:#b2dba1}.addon .addon-status span{line-height:28px}.addon .addon-status .button-primary{float:right}.upgrade-info .upgrade-info-title{font-size:24px}.upgrade-info .upgrade-info-list li{display:inline-block;margin-right:20px}@media only screen and (max-width:1040px){.toolbar-container .media-toolbar .media-toolbar-primary,.toolbar-container .media-toolbar .media-toolbar-secondary{max-width:100%;float:none}.toolbar-container .media-toolbar .media-toolbar-primary{text-align:left}}@media only screen and (max-width:900px){.attachment-info .setting .link-options{width:100%;float:none}}@media only screen and (max-width:782px){.wp-list-table .column-post_title{width:75%}.wp-list-table .column-post_author,.wp-list-table .column-post_date,.wp-list-table .column-shortcode,.wp-list-table .column-template_function{display:none}}@media only screen and (max-width:640px){.attachment-info .media-modal,.media-modal{left:0!important;right:0!important}.media-modal input[type=url],.media-modal input[type=text],.media-modal select,.media-modal textarea{font-size:16px;padding:6px 10px}.attachment-info .setting .link-options{width:100%;float:none;margin:1px}.attachment-info .setting .link-options label{margin-top:8px}.toolbar-container .media-toolbar .media-toolbar-primary{margin-bottom:15px}.toolbar-container .media-toolbar .media-toolbar-secondary{margin-top:10px}.toolbar-container .media-toolbar .randomize{display:block;float:none}.toolbar-container .media-toolbar .media-button{float:none;margin:0 10px 10px 0}.main-container{margin-right:0}.slides-container{float:none}#slides-browser .ui-sortable{min-height:100px}.settings-container{float:none;margin-top:20px;margin-right:0;width:100%}}
assets/css/public.css ADDED
@@ -0,0 +1,465 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Core Owl Carousel CSS File
3
+ * v1.3.2
4
+ */
5
+
6
+ /* clearfix */
7
+ .easingslider-container .easingslider-wrapper:after {
8
+ content: ".";
9
+ display: block;
10
+ clear: both;
11
+ visibility: hidden;
12
+ line-height: 0;
13
+ height: 0;
14
+ }
15
+ /* display none until init */
16
+ .easingslider-container{
17
+ display: none;
18
+ position: relative;
19
+ width: 100%;
20
+ -ms-touch-action: pan-y;
21
+ }
22
+ .easingslider-container .easingslider-wrapper{
23
+ display: none;
24
+ position: relative;
25
+ -webkit-transform: translate3d(0px, 0px, 0px);
26
+ }
27
+ .easingslider-container .easingslider-wrapper-outer{
28
+ overflow: hidden;
29
+ position: relative;
30
+ width: 100%;
31
+ }
32
+ .easingslider-container .easingslider-wrapper-outer.autoHeight{
33
+ -webkit-transition: height 500ms ease-in-out;
34
+ -moz-transition: height 500ms ease-in-out;
35
+ -ms-transition: height 500ms ease-in-out;
36
+ -o-transition: height 500ms ease-in-out;
37
+ transition: height 500ms ease-in-out;
38
+ }
39
+
40
+ .easingslider-container .easingslider-item{
41
+ float: left;
42
+ }
43
+ .easingslider-controls .easingslider-page,
44
+ .easingslider-controls .easingslider-buttons div{
45
+ cursor: pointer;
46
+ }
47
+ .easingslider-controls {
48
+ -webkit-user-select: none;
49
+ -khtml-user-select: none;
50
+ -moz-user-select: none;
51
+ -ms-user-select: none;
52
+ user-select: none;
53
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
54
+ }
55
+
56
+ /* mouse grab icon */
57
+ .grabbing {
58
+ cursor:url(grabbing.png) 8 8, move;
59
+ }
60
+
61
+ /* fix */
62
+ .easingslider-container .easingslider-wrapper,
63
+ .easingslider-container .easingslider-item{
64
+ -webkit-backface-visibility: hidden;
65
+ -moz-backface-visibility: hidden;
66
+ -ms-backface-visibility: hidden;
67
+ -webkit-transform: translate3d(0,0,0);
68
+ -moz-transform: translate3d(0,0,0);
69
+ -ms-transform: translate3d(0,0,0);
70
+ }
71
+
72
+
73
+ /*
74
+ * Owl Carousel CSS3 Transitions
75
+ * v1.3.2
76
+ */
77
+
78
+ .easingslider-origin {
79
+ -webkit-perspective: 1200px;
80
+ -webkit-perspective-origin-x : 50%;
81
+ -webkit-perspective-origin-y : 50%;
82
+ -moz-perspective : 1200px;
83
+ -moz-perspective-origin-x : 50%;
84
+ -moz-perspective-origin-y : 50%;
85
+ perspective : 1200px;
86
+ }
87
+ /* fade */
88
+ .easingslider-fade-out {
89
+ z-index: 10;
90
+ -webkit-animation: fadeOut .7s both ease;
91
+ -moz-animation: fadeOut .7s both ease;
92
+ animation: fadeOut .7s both ease;
93
+ }
94
+ .easingslider-fade-in {
95
+ -webkit-animation: fadeIn .7s both ease;
96
+ -moz-animation: fadeIn .7s both ease;
97
+ animation: fadeIn .7s both ease;
98
+ }
99
+ /* backSlide */
100
+ .easingslider-backSlide-out {
101
+ -webkit-animation: backSlideOut 1s both ease;
102
+ -moz-animation: backSlideOut 1s both ease;
103
+ animation: backSlideOut 1s both ease;
104
+ }
105
+ .easingslider-backSlide-in {
106
+ -webkit-animation: backSlideIn 1s both ease;
107
+ -moz-animation: backSlideIn 1s both ease;
108
+ animation: backSlideIn 1s both ease;
109
+ }
110
+ /* goDown */
111
+ .easingslider-goDown-out {
112
+ -webkit-animation: scaleToFade .7s ease both;
113
+ -moz-animation: scaleToFade .7s ease both;
114
+ animation: scaleToFade .7s ease both;
115
+ }
116
+ .easingslider-goDown-in {
117
+ -webkit-animation: goDown .6s ease both;
118
+ -moz-animation: goDown .6s ease both;
119
+ animation: goDown .6s ease both;
120
+ }
121
+ /* scaleUp */
122
+ .easingslider-fadeUp-in {
123
+ -webkit-animation: scaleUpFrom .5s ease both;
124
+ -moz-animation: scaleUpFrom .5s ease both;
125
+ animation: scaleUpFrom .5s ease both;
126
+ }
127
+
128
+ .easingslider-fadeUp-out {
129
+ -webkit-animation: scaleUpTo .5s ease both;
130
+ -moz-animation: scaleUpTo .5s ease both;
131
+ animation: scaleUpTo .5s ease both;
132
+ }
133
+ /* Keyframes */
134
+ /*empty*/
135
+ @-webkit-keyframes empty {
136
+ 0% {opacity: 1}
137
+ }
138
+ @-moz-keyframes empty {
139
+ 0% {opacity: 1}
140
+ }
141
+ @keyframes empty {
142
+ 0% {opacity: 1}
143
+ }
144
+ @-webkit-keyframes fadeIn {
145
+ 0% { opacity:0; }
146
+ 100% { opacity:1; }
147
+ }
148
+ @-moz-keyframes fadeIn {
149
+ 0% { opacity:0; }
150
+ 100% { opacity:1; }
151
+ }
152
+ @keyframes fadeIn {
153
+ 0% { opacity:0; }
154
+ 100% { opacity:1; }
155
+ }
156
+ @-webkit-keyframes fadeOut {
157
+ 0% { opacity:1; }
158
+ 100% { opacity:0; }
159
+ }
160
+ @-moz-keyframes fadeOut {
161
+ 0% { opacity:1; }
162
+ 100% { opacity:0; }
163
+ }
164
+ @keyframes fadeOut {
165
+ 0% { opacity:1; }
166
+ 100% { opacity:0; }
167
+ }
168
+ @-webkit-keyframes backSlideOut {
169
+ 25% { opacity: .5; -webkit-transform: translateZ(-500px); }
170
+ 75% { opacity: .5; -webkit-transform: translateZ(-500px) translateX(-200%); }
171
+ 100% { opacity: .5; -webkit-transform: translateZ(-500px) translateX(-200%); }
172
+ }
173
+ @-moz-keyframes backSlideOut {
174
+ 25% { opacity: .5; -moz-transform: translateZ(-500px); }
175
+ 75% { opacity: .5; -moz-transform: translateZ(-500px) translateX(-200%); }
176
+ 100% { opacity: .5; -moz-transform: translateZ(-500px) translateX(-200%); }
177
+ }
178
+ @keyframes backSlideOut {
179
+ 25% { opacity: .5; transform: translateZ(-500px); }
180
+ 75% { opacity: .5; transform: translateZ(-500px) translateX(-200%); }
181
+ 100% { opacity: .5; transform: translateZ(-500px) translateX(-200%); }
182
+ }
183
+ @-webkit-keyframes backSlideIn {
184
+ 0%, 25% { opacity: .5; -webkit-transform: translateZ(-500px) translateX(200%); }
185
+ 75% { opacity: .5; -webkit-transform: translateZ(-500px); }
186
+ 100% { opacity: 1; -webkit-transform: translateZ(0) translateX(0); }
187
+ }
188
+ @-moz-keyframes backSlideIn {
189
+ 0%, 25% { opacity: .5; -moz-transform: translateZ(-500px) translateX(200%); }
190
+ 75% { opacity: .5; -moz-transform: translateZ(-500px); }
191
+ 100% { opacity: 1; -moz-transform: translateZ(0) translateX(0); }
192
+ }
193
+ @keyframes backSlideIn {
194
+ 0%, 25% { opacity: .5; transform: translateZ(-500px) translateX(200%); }
195
+ 75% { opacity: .5; transform: translateZ(-500px); }
196
+ 100% { opacity: 1; transform: translateZ(0) translateX(0); }
197
+ }
198
+ @-webkit-keyframes scaleToFade {
199
+ to { opacity: 0; -webkit-transform: scale(.8); }
200
+ }
201
+ @-moz-keyframes scaleToFade {
202
+ to { opacity: 0; -moz-transform: scale(.8); }
203
+ }
204
+ @keyframes scaleToFade {
205
+ to { opacity: 0; transform: scale(.8); }
206
+ }
207
+ @-webkit-keyframes goDown {
208
+ from { -webkit-transform: translateY(-100%); }
209
+ }
210
+ @-moz-keyframes goDown {
211
+ from { -moz-transform: translateY(-100%); }
212
+ }
213
+ @keyframes goDown {
214
+ from { transform: translateY(-100%); }
215
+ }
216
+
217
+ @-webkit-keyframes scaleUpFrom {
218
+ from { opacity: 0; -webkit-transform: scale(1.5); }
219
+ }
220
+ @-moz-keyframes scaleUpFrom {
221
+ from { opacity: 0; -moz-transform: scale(1.5); }
222
+ }
223
+ @keyframes scaleUpFrom {
224
+ from { opacity: 0; transform: scale(1.5); }
225
+ }
226
+
227
+ @-webkit-keyframes scaleUpTo {
228
+ to { opacity: 0; -webkit-transform: scale(1.5); }
229
+ }
230
+ @-moz-keyframes scaleUpTo {
231
+ to { opacity: 0; -moz-transform: scale(1.5); }
232
+ }
233
+ @keyframes scaleUpTo {
234
+ to { opacity: 0; transform: scale(1.5); }
235
+ }
236
+ /* Slides
237
+ -------------------------------------------------------------- */
238
+ .easingslider-slide {
239
+ background-color: #fff;
240
+ }
241
+
242
+ /* Images
243
+ -------------------------------------------------------------- */
244
+ .easingslider-image {
245
+ margin-top: 0 !important;
246
+ margin-bottom: 0 !important;
247
+ padding: 0 !important;
248
+ }
249
+
250
+ /* Links
251
+ -------------------------------------------------------------- */
252
+ .easingslider-link {
253
+ display: block;
254
+ }
255
+
256
+ /* Lazy Loading
257
+ -------------------------------------------------------------- */
258
+ .easingslider-item.loading {
259
+ background-image: url(../images/loading.gif);
260
+ background-repeat: no-repeat;
261
+ background-position: center center;
262
+ background-color: #fff;
263
+ }
264
+
265
+ /* Arrows
266
+ -------------------------------------------------------------- */
267
+ .easingslider-prev,
268
+ .easingslider-next {
269
+ position: absolute;
270
+ top: 50%;
271
+ width: 30px;
272
+ height: 30px;
273
+ margin-top: -15px;
274
+ background-repeat: no-repeat;
275
+ z-index: 40;
276
+ cursor: pointer;
277
+ }
278
+
279
+ .easingslider-next {
280
+ background-image: url(../images/nav-arrow-next.png);
281
+ background-position: top right;
282
+ }
283
+
284
+ .easingslider-prev {
285
+ background-image: url(../images/nav-arrow-prev.png);
286
+ background-position: top left;
287
+ }
288
+
289
+ .easingslider-arrows-inside .easingslider-next {
290
+ right: 10px;
291
+ }
292
+
293
+ .easingslider-arrows-inside .easingslider-prev {
294
+ left: 10px;
295
+ }
296
+
297
+ .easingslider-arrows-outside .easingslider-next {
298
+ right: -40px;
299
+ padding-left: 20px;
300
+ }
301
+
302
+ .easingslider-arrows-outside .easingslider-prev {
303
+ left: -40px;
304
+ padding-right: 20px;
305
+ }
306
+
307
+ .easingslider-arrows-hover .easingslider-prev,
308
+ .easingslider-arrows-hover .easingslider-next {
309
+ opacity: 0;
310
+ -webkit-transition: opacity 0.3s ease, -webkit-transform 0.1s ease-in;
311
+ -moz-transition: opacity 0.3s ease, -moz-transform 0.1s ease-in;
312
+ -ms-transition: opacity 0.3s ease, -ms-transform 0.1s ease-in;
313
+ -o-transition: opacity 0.3s ease, -o-transform 0.1s ease-in;
314
+ transition: opacity 0.3s ease, transform 0.1s ease-in;
315
+ }
316
+
317
+ .easingslider-arrows-hover .easingslider-prev {
318
+ -webkit-transform: translate3d(-10px, 0, 0);
319
+ -moz-transform: translate3d(-10px, 0, 0);
320
+ -ms-transform: translate3d(-10px, 0, 0);
321
+ -o-transform: translate3d(-10px, 0, 0);
322
+ transform: translate3d(-10px, 0, 0);
323
+ }
324
+
325
+ .easingslider-arrows-hover .easingslider-next {
326
+ -webkit-transform: translate3d(10px, 0, 0);
327
+ -moz-transform: translate3d(10px, 0, 0);
328
+ -ms-transform: translate3d(10px, 0, 0);
329
+ -o-transform: translate3d(10px, 0, 0);
330
+ transform: translate3d(10px, 0, 0);
331
+ }
332
+
333
+ .easingslider-arrows-hover:hover .easingslider-prev,
334
+ .easingslider-arrows-hover:hover .easingslider-next {
335
+ opacity: 1;
336
+ -webkit-transform: translate3d(0, 0, 0);
337
+ -moz-transform: translate3d(0, 0, 0);
338
+ -ms-transform: translate3d(0, 0, 0);
339
+ -o-transform: translate3d(0, 0, 0);
340
+ transform: translate3d(0, 0, 0);
341
+ }
342
+
343
+ /* Pagination
344
+ -------------------------------------------------------------- */
345
+ .easingslider-pagination {
346
+ position: absolute;
347
+ height: 17px;
348
+ z-index: 40;
349
+ }
350
+
351
+ .easingslider-pagination .easingslider-page {
352
+ display: inline-block;
353
+ *display: inline; /** IE7 hack */
354
+ zoom: 1; /** IE7 hack */
355
+ }
356
+
357
+ .easingslider-pagination .easingslider-page span {
358
+ width: 15px;
359
+ height: 15px;
360
+ margin: 0 2px 0 0;
361
+ padding: 0;
362
+ background-image: url(../images/nav-icon-inactive.png);
363
+ background-repeat: no-repeat;
364
+ background-position: 0 0;
365
+ display: block;
366
+ z-index: 40;
367
+ cursor: pointer;
368
+ }
369
+
370
+ .easingslider-pagination .easingslider-page:last-child span {
371
+ margin-right: 0;
372
+ }
373
+
374
+ .easingslider-pagination .easingslider-page.active span {
375
+ background-image: url(../images/nav-icon-active.png);
376
+ }
377
+
378
+ .easingslider-pagination-inside.easingslider-pagination-bottom-left .easingslider-pagination {
379
+ bottom: 10px;
380
+ left: 10px;
381
+ }
382
+
383
+ .easingslider-pagination-inside.easingslider-pagination-bottom-right .easingslider-pagination {
384
+ bottom: 10px;
385
+ right: 10px;
386
+ }
387
+
388
+ .easingslider-pagination-inside.easingslider-pagination-bottom-center .easingslider-pagination {
389
+ bottom: 10px;
390
+ left: 0;
391
+ width: 100%;
392
+ text-align: center;
393
+ }
394
+
395
+ .easingslider-pagination-inside.easingslider-pagination-top-left .easingslider-pagination {
396
+ top: 10px;
397
+ left: 10px;
398
+ }
399
+
400
+ .easingslider-pagination-inside.easingslider-pagination-top-right .easingslider-pagination {
401
+ top: 10px;
402
+ right: 10px;
403
+ }
404
+
405
+ .easingslider-pagination-inside.easingslider-pagination-top-center .easingslider-pagination {
406
+ top: 10px;
407
+ left: 0;
408
+ right: 0;
409
+ width: 100%;
410
+ text-align: center;
411
+ }
412
+
413
+ .easingslider-pagination-outside.easingslider-pagination-bottom-left .easingslider-pagination {
414
+ bottom: -25px;
415
+ left: 0;
416
+ padding-top: 20px;
417
+ }
418
+
419
+ .easingslider-pagination-outside.easingslider-pagination-bottom-right .easingslider-pagination {
420
+ bottom: -25px;
421
+ right: 0;
422
+ padding-top: 20px;
423
+ }
424
+
425
+ .easingslider-pagination-outside.easingslider-pagination-bottom-center .easingslider-pagination {
426
+ bottom: -25px;
427
+ left: 0;
428
+ right: 0;
429
+ width: 100%;
430
+ text-align: center;
431
+ padding-top: 20px;
432
+ }
433
+
434
+ .easingslider-pagination-outside.easingslider-pagination-top-left .easingslider-pagination {
435
+ top: -25px;
436
+ left: 0;
437
+ padding-bottom: 20px;
438
+ }
439
+
440
+ .easingslider-pagination-outside.easingslider-pagination-top-right .easingslider-pagination {
441
+ top: -25px;
442
+ right: 0;
443
+ padding-bottom: 20px;
444
+ }
445
+
446
+ .easingslider-pagination-outside.easingslider-pagination-top-center .easingslider-pagination {
447
+ top: -25px;
448
+ left: 0;
449
+ width: 100%;
450
+ text-align: center;
451
+ padding-bottom: 20px;
452
+ }
453
+
454
+ .easingslider-pagination-hover .easingslider-pagination {
455
+ opacity: 0;
456
+ -webkit-transition: opacity 0.3s ease;
457
+ -moz-transition: opacity 0.3s ease;
458
+ -ms-transition: opacity 0.3s ease;
459
+ -o-transition: opacity 0.3s ease;
460
+ transition: opacity 0.3s ease;
461
+ }
462
+
463
+ .easingslider-pagination-hover:hover .easingslider-pagination {
464
+ opacity: 1;
465
+ }
assets/css/public.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .easingslider-container .easingslider-wrapper:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}.easingslider-container,.easingslider-container .easingslider-wrapper{display:none;position:relative}.easingslider-container{width:100%;-ms-touch-action:pan-y}.easingslider-container .easingslider-wrapper-outer{overflow:hidden;position:relative;width:100%}.easingslider-container .easingslider-wrapper-outer.autoHeight{-webkit-transition:height .5s ease-in-out;-moz-transition:height .5s ease-in-out;-ms-transition:height .5s ease-in-out;-o-transition:height .5s ease-in-out;transition:height .5s ease-in-out}.easingslider-container .easingslider-item{float:left}.easingslider-controls .easingslider-buttons div,.easingslider-controls .easingslider-page{cursor:pointer}.easingslider-controls{-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.grabbing{cursor:url(grabbing.png) 8 8,move}.easingslider-container .easingslider-item,.easingslider-container .easingslider-wrapper{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}.easingslider-origin{-webkit-perspective:1200px;-webkit-perspective-origin-x:50%;-webkit-perspective-origin-y:50%;-moz-perspective:1200px;-moz-perspective-origin-x:50%;-moz-perspective-origin-y:50%;perspective:1200px}.easingslider-fade-out{z-index:10;-webkit-animation:fadeOut .7s both ease;-moz-animation:fadeOut .7s both ease;animation:fadeOut .7s both ease}.easingslider-fade-in{-webkit-animation:fadeIn .7s both ease;-moz-animation:fadeIn .7s both ease;animation:fadeIn .7s both ease}.easingslider-backSlide-out{-webkit-animation:backSlideOut 1s both ease;-moz-animation:backSlideOut 1s both ease;animation:backSlideOut 1s both ease}.easingslider-backSlide-in{-webkit-animation:backSlideIn 1s both ease;-moz-animation:backSlideIn 1s both ease;animation:backSlideIn 1s both ease}.easingslider-goDown-out{-webkit-animation:scaleToFade .7s ease both;-moz-animation:scaleToFade .7s ease both;animation:scaleToFade .7s ease both}.easingslider-goDown-in{-webkit-animation:goDown .6s ease both;-moz-animation:goDown .6s ease both;animation:goDown .6s ease both}.easingslider-fadeUp-in{-webkit-animation:scaleUpFrom .5s ease both;-moz-animation:scaleUpFrom .5s ease both;animation:scaleUpFrom .5s ease both}.easingslider-fadeUp-out{-webkit-animation:scaleUpTo .5s ease both;-moz-animation:scaleUpTo .5s ease both;animation:scaleUpTo .5s ease both}@-webkit-keyframes empty{0%{opacity:1}}@-moz-keyframes empty{0%{opacity:1}}@keyframes empty{0%{opacity:1}}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-moz-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-moz-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-webkit-keyframes backSlideOut{25%{opacity:.5;-webkit-transform:translateZ(-500px)}100%,75%{opacity:.5;-webkit-transform:translateZ(-500px) translateX(-200%)}}@-moz-keyframes backSlideOut{25%{opacity:.5;-moz-transform:translateZ(-500px)}100%,75%{opacity:.5;-moz-transform:translateZ(-500px) translateX(-200%)}}@keyframes backSlideOut{25%{opacity:.5;transform:translateZ(-500px)}100%,75%{opacity:.5;transform:translateZ(-500px) translateX(-200%)}}@-webkit-keyframes backSlideIn{0%,25%{opacity:.5;-webkit-transform:translateZ(-500px) translateX(200%)}75%{opacity:.5;-webkit-transform:translateZ(-500px)}100%{opacity:1;-webkit-transform:translateZ(0) translateX(0)}}@-moz-keyframes backSlideIn{0%,25%{opacity:.5;-moz-transform:translateZ(-500px) translateX(200%)}75%{opacity:.5;-moz-transform:translateZ(-500px)}100%{opacity:1;-moz-transform:translateZ(0) translateX(0)}}@keyframes backSlideIn{0%,25%{opacity:.5;transform:translateZ(-500px) translateX(200%)}75%{opacity:.5;transform:translateZ(-500px)}100%{opacity:1;transform:translateZ(0) translateX(0)}}@-webkit-keyframes scaleToFade{to{opacity:0;-webkit-transform:scale(.8)}}@-moz-keyframes scaleToFade{to{opacity:0;-moz-transform:scale(.8)}}@keyframes scaleToFade{to{opacity:0;transform:scale(.8)}}@-webkit-keyframes goDown{from{-webkit-transform:translateY(-100%)}}@-moz-keyframes goDown{from{-moz-transform:translateY(-100%)}}@keyframes goDown{from{transform:translateY(-100%)}}@-webkit-keyframes scaleUpFrom{from{opacity:0;-webkit-transform:scale(1.5)}}@-moz-keyframes scaleUpFrom{from{opacity:0;-moz-transform:scale(1.5)}}@keyframes scaleUpFrom{from{opacity:0;transform:scale(1.5)}}@-webkit-keyframes scaleUpTo{to{opacity:0;-webkit-transform:scale(1.5)}}@-moz-keyframes scaleUpTo{to{opacity:0;-moz-transform:scale(1.5)}}@keyframes scaleUpTo{to{opacity:0;transform:scale(1.5)}}.easingslider-slide{background-color:#fff}.easingslider-image{margin-top:0!important;margin-bottom:0!important;padding:0!important}.easingslider-link{display:block}.easingslider-item.loading{background-image:url(../images/loading.gif);background-repeat:no-repeat;background-position:center center;background-color:#fff}.easingslider-next,.easingslider-prev{position:absolute;top:50%;width:30px;height:30px;margin-top:-15px;background-repeat:no-repeat;z-index:40;cursor:pointer}.easingslider-next{background-image:url(../images/nav-arrow-next.png);background-position:top right}.easingslider-prev{background-image:url(../images/nav-arrow-prev.png);background-position:top left}.easingslider-arrows-inside .easingslider-next{right:10px}.easingslider-arrows-inside .easingslider-prev{left:10px}.easingslider-arrows-outside .easingslider-next{right:-40px;padding-left:20px}.easingslider-arrows-outside .easingslider-prev{left:-40px;padding-right:20px}.easingslider-arrows-hover .easingslider-next,.easingslider-arrows-hover .easingslider-prev{opacity:0;-webkit-transition:opacity .3s ease,-webkit-transform .1s ease-in;-moz-transition:opacity .3s ease,-moz-transform .1s ease-in;-ms-transition:opacity .3s ease,-ms-transform .1s ease-in;-o-transition:opacity .3s ease,-o-transform .1s ease-in;transition:opacity .3s ease,transform .1s ease-in}.easingslider-arrows-hover .easingslider-prev{-webkit-transform:translate3d(-10px,0,0);-moz-transform:translate3d(-10px,0,0);-ms-transform:translate3d(-10px,0,0);-o-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}.easingslider-arrows-hover .easingslider-next{-webkit-transform:translate3d(10px,0,0);-moz-transform:translate3d(10px,0,0);-ms-transform:translate3d(10px,0,0);-o-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}.easingslider-arrows-hover:hover .easingslider-next,.easingslider-arrows-hover:hover .easingslider-prev{opacity:1;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.easingslider-pagination{position:absolute;height:17px;z-index:40}.easingslider-pagination .easingslider-page{display:inline-block;zoom:1}.easingslider-pagination .easingslider-page span{width:15px;height:15px;margin:0 2px 0 0;padding:0;background-image:url(../images/nav-icon-inactive.png);background-repeat:no-repeat;background-position:0 0;display:block;z-index:40;cursor:pointer}.easingslider-pagination .easingslider-page:last-child span{margin-right:0}.easingslider-pagination .easingslider-page.active span{background-image:url(../images/nav-icon-active.png)}.easingslider-pagination-inside.easingslider-pagination-bottom-left .easingslider-pagination{bottom:10px;left:10px}.easingslider-pagination-inside.easingslider-pagination-bottom-right .easingslider-pagination{bottom:10px;right:10px}.easingslider-pagination-inside.easingslider-pagination-bottom-center .easingslider-pagination{bottom:10px;left:0;width:100%;text-align:center}.easingslider-pagination-inside.easingslider-pagination-top-left .easingslider-pagination{top:10px;left:10px}.easingslider-pagination-inside.easingslider-pagination-top-right .easingslider-pagination{top:10px;right:10px}.easingslider-pagination-inside.easingslider-pagination-top-center .easingslider-pagination{top:10px;left:0;right:0;width:100%;text-align:center}.easingslider-pagination-outside.easingslider-pagination-bottom-left .easingslider-pagination{bottom:-25px;left:0;padding-top:20px}.easingslider-pagination-outside.easingslider-pagination-bottom-right .easingslider-pagination{bottom:-25px;right:0;padding-top:20px}.easingslider-pagination-outside.easingslider-pagination-bottom-center .easingslider-pagination{bottom:-25px;left:0;right:0;width:100%;text-align:center;padding-top:20px}.easingslider-pagination-outside.easingslider-pagination-top-left .easingslider-pagination{top:-25px;left:0;padding-bottom:20px}.easingslider-pagination-outside.easingslider-pagination-top-right .easingslider-pagination{top:-25px;right:0;padding-bottom:20px}.easingslider-pagination-outside.easingslider-pagination-top-center .easingslider-pagination{top:-25px;left:0;width:100%;text-align:center;padding-bottom:20px}.easingslider-pagination-hover .easingslider-pagination{opacity:0;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease}.easingslider-pagination-hover:hover .easingslider-pagination{opacity:1}
{images → assets/images}/easingslider-badge.jpg RENAMED
File without changes
{images → assets/images}/function-screenshot.jpg RENAMED
File without changes
{images → assets/images}/interface-screenshot.jpg RENAMED
File without changes
{images → assets/images}/list-screenshot.jpg RENAMED
File without changes
{images → assets/images}/loading.gif RENAMED
File without changes
{images → assets/images}/loading@2x.gif RENAMED
File without changes
{images → assets/images}/nav-arrow-next.png RENAMED
File without changes
{images → assets/images}/nav-arrow-next@2x.png RENAMED
File without changes
{images → assets/images}/nav-arrow-prev.png RENAMED
File without changes
{images → assets/images}/nav-arrow-prev@2x.png RENAMED
File without changes
{images → assets/images}/nav-icon-active.png RENAMED
File without changes
{images → assets/images}/nav-icon-active@2x.png RENAMED
File without changes
{images → assets/images}/nav-icon-inactive.png RENAMED
File without changes
{images → assets/images}/nav-icon-inactive@2x.png RENAMED
File without changes
assets/images/placeholder-pixel.png ADDED
Binary file
{images → assets/images}/pro-bundle.png RENAMED
File without changes
{images → assets/images}/shadow.png RENAMED
File without changes
{images → assets/images}/shortcode-screenshot.jpg RENAMED
File without changes
{images → assets/images}/welcome-screenshot.jpg RENAMED
File without changes
{images → assets/images}/widget-screenshot.jpg RENAMED
File without changes
assets/js/admin.js ADDED
@@ -0,0 +1,2157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Namespace
3
+ */
4
+ window.EasingSlider = window.EasingSlider || {};
5
+ window.EasingSlider.Admin = window.EasingSlider.Admin || {};
6
+
7
+ // Add our components
8
+ _.extend(EasingSlider.Admin, {
9
+ model: {},
10
+ collection: {},
11
+ controller: {},
12
+ frame: {},
13
+ view: {},
14
+ toolbar: {},
15
+ router: {},
16
+ Router: {}
17
+ });
18
+
19
+ /**
20
+ * Defines the admin functionality
21
+ */
22
+ (function($) {
23
+
24
+ var Admin = window.EasingSlider.Admin;
25
+
26
+ /**
27
+ * Returns the appropriate "Slide" model
28
+ */
29
+ Admin.model.Slide = {
30
+
31
+ /**
32
+ * Get the appropriate model
33
+ */
34
+ get: function(attributes) {
35
+
36
+ if ( 'undefined' !== typeof Admin.model.Slide[attributes.type] ) {
37
+ return new Admin.model.Slide[attributes.type](attributes);
38
+ }
39
+
40
+ return new Admin.model.Slide.base(attributes);
41
+
42
+ }
43
+
44
+ };
45
+
46
+ /**
47
+ * Base Slide Model
48
+ */
49
+ Admin.model.Slide.base = Backbone.Model.extend();
50
+
51
+ /**
52
+ * "Image" Slide Model
53
+ */
54
+ Admin.model.Slide.image = Admin.model.Slide.base.extend({
55
+
56
+ /**
57
+ * Attachment
58
+ */
59
+ attachment: false,
60
+
61
+ /**
62
+ * Defaults
63
+ */
64
+ defaults: {
65
+ attachment_id: null,
66
+ type: 'image',
67
+ alt: '',
68
+ link: 'none',
69
+ linkUrl: '',
70
+ linkTargetBlank: false,
71
+ title: '',
72
+ url: null
73
+ }
74
+
75
+ });
76
+
77
+ /**
78
+ * Slides Collection
79
+ */
80
+ Admin.collection.Slides = Backbone.Collection.extend({
81
+
82
+ /**
83
+ * The models for this collection are polymorphic,
84
+ * so the model to add is determined by function.
85
+ *
86
+ * Don't be fooled, Admin.model.Slide.get is just a function (not a model).
87
+ */
88
+ model: Admin.model.Slide.get,
89
+
90
+ /**
91
+ * Constructor
92
+ */
93
+ initialize: function() {
94
+
95
+ // Bind our collection events
96
+ this.on('add', this._resetIDs, this);
97
+ this.on('remove', this._resetIDs, this);
98
+ this.on('reset', this._resetIDs, this);
99
+
100
+ },
101
+
102
+ /**
103
+ * Comparator
104
+ */
105
+ comparator: function(model) {
106
+
107
+ return model.get('id');
108
+
109
+ },
110
+
111
+ /**
112
+ * Resets the ID attribute on each model
113
+ */
114
+ _resetIDs: function() {
115
+
116
+ // Create a new collection. We need to do this to avoid issues with duplicate IDs.
117
+ var collection = new Backbone.Collection();
118
+
119
+ // Loop through each model and update the ID attribute. Then add it to our collection.
120
+ _.each(this.models, function(model, index) {
121
+ model.set({ id: index + 1 });
122
+
123
+ collection.add(model);
124
+ });
125
+
126
+ // Reset this collection with the models from our temporary collection
127
+ this.reset(collection.models, { silent: true });
128
+
129
+ },
130
+
131
+ /**
132
+ * Repositions a model to the specified index in the collection
133
+ */
134
+ reposition: function(model, index) {
135
+
136
+ // Remove the model
137
+ this.remove(model, { silent: true });
138
+
139
+ // Add the model at our desired index
140
+ this.add(model, { at: index, silent: true });
141
+
142
+ // Reset the IDs
143
+ this._resetIDs();
144
+
145
+ return this;
146
+
147
+ },
148
+
149
+ /**
150
+ * Syncs the models in this collection
151
+ */
152
+ sync: function() {
153
+
154
+ var collection = this,
155
+ ids = [];
156
+
157
+ // Loop through each model and get attachment IDs
158
+ _.each(this.models, function(model) {
159
+
160
+ // Check if the model has an attachment ID
161
+ if ( model.has('attachment_id') ) {
162
+ ids.push(model.get('attachment_id'));
163
+ }
164
+
165
+ }, this);
166
+
167
+ // Query the WordPress Media Library
168
+ var query = wp.media.query({
169
+ post__in: ids,
170
+ posts_per_page: -1
171
+ });
172
+
173
+ // Do the query
174
+ query.more().done(function() {
175
+ _.each(query.models, function(attachment) {
176
+
177
+ // Get models with a matching ID
178
+ var matches = collection.where({ attachment_id: attachment.get('id') });
179
+
180
+ // Loop through each match
181
+ _.each(matches, function(model) {
182
+
183
+ // Set the attachment object
184
+ model.attachment = attachment;
185
+
186
+ });
187
+
188
+ });
189
+
190
+ // Trigger a sync action
191
+ collection.trigger('sync:done');
192
+ });
193
+
194
+ return this;
195
+
196
+ }
197
+
198
+ });
199
+
200
+ /**
201
+ * Returns the appropriate "Add Slide" controller
202
+ */
203
+ Admin.controller.AddSlide = {
204
+
205
+ /**
206
+ * Get the appropriate controller
207
+ */
208
+ get: function(options) {
209
+
210
+ if ( 'undefined' !== typeof Admin.controller.AddSlide[options.type] ) {
211
+ return new Admin.controller.AddSlide[options.type](options);
212
+ }
213
+
214
+ return new Admin.controller.AddSlide.base(options);
215
+
216
+ }
217
+
218
+ };
219
+
220
+ /**
221
+ * Base "Add Slide" Controller
222
+ */
223
+ Admin.controller.AddSlide.base = wp.media.controller.State.extend({
224
+
225
+ /**
226
+ * Constructor
227
+ */
228
+ initialize: function() {
229
+
230
+ // Get the model
231
+ this.props = new Admin.model.Slide.get({
232
+ type: this.get('type')
233
+ });
234
+
235
+ }
236
+
237
+ });
238
+
239
+ /**
240
+ * Image "Add Slide" Controller
241
+ */
242
+ Admin.controller.AddSlide.image = wp.media.controller.Library.extend();
243
+
244
+ /**
245
+ * Returns the appropriate "Edit Slide" controller
246
+ */
247
+ Admin.controller.EditSlide = {
248
+
249
+ /**
250
+ * Get the appropriate controller
251
+ */
252
+ get: function(options) {
253
+
254
+ if ( 'undefined' !== typeof Admin.controller.EditSlide[options.type] ) {
255
+ return new Admin.controller.EditSlide[options.type](options);
256
+ }
257
+
258
+ return new Admin.controller.EditSlide.base(options);
259
+
260
+ }
261
+
262
+ };
263
+
264
+ /**
265
+ * Base "Edit Slide" Controller
266
+ */
267
+ Admin.controller.EditSlide.base = wp.media.controller.State.extend({
268
+
269
+ /**
270
+ * Defaults
271
+ */
272
+ defaults: _.defaults({
273
+ id: 'edit-slide',
274
+ title: _easingsliderAdminL10n.media_upload.title,
275
+ content: 'edit-slide',
276
+ menu: false,
277
+ router: false,
278
+ toolbar: 'edit-slide',
279
+ editing: false,
280
+ priority: 60
281
+ }, wp.media.controller.State.defaults )
282
+
283
+ });
284
+
285
+ /**
286
+ * Image "Edit Slide" Controller
287
+ */
288
+ Admin.controller.EditSlide.image = Admin.controller.EditSlide.base.extend();
289
+
290
+ /**
291
+ * "Add Slide" Frame
292
+ */
293
+ Admin.frame.AddSlide = wp.media.view.MediaFrame.Post.extend({
294
+
295
+ /**
296
+ * Constructor
297
+ */
298
+ initialize: function() {
299
+
300
+ // Alter defaults
301
+ _.defaults(this.options, {
302
+ multiple: true
303
+ });
304
+
305
+ // Call parent constructor
306
+ wp.media.view.MediaFrame.Post.prototype.initialize.apply(this, arguments);
307
+
308
+ },
309
+
310
+ /**
311
+ * Bind event handlers
312
+ */
313
+ bindHandlers: function() {
314
+
315
+ // Bind Handlers
316
+ this.on('close', this.updateRouter, this);
317
+ this.on('content:render:browse', this.removeSidebar, this);
318
+ this.on('toolbar:create:insert-slide', this.createToolbar, this);
319
+ this.on('toolbar:render:insert-slide', this.insertToolbar, this);
320
+
321
+ // Call parent
322
+ wp.media.view.MediaFrame.Post.prototype.bindHandlers.apply(this, arguments);
323
+
324
+ },
325
+
326
+ /**
327
+ * Render callback for the content region in the 'browse' mode.
328
+ */
329
+ browseContent: function(contentRegion) {
330
+
331
+ // Get the state
332
+ var state = this.state();
333
+
334
+ // Show the toolbar
335
+ this.$el.removeClass('hide-toolbar');
336
+
337
+ // Browse our library of attachments
338
+ contentRegion.view = new Admin.view.AddSlide.image({
339
+ controller: this,
340
+ collection: state.get('library'),
341
+ selection: state.get('selection'),
342
+ model: state,
343
+ sortable: state.get('sortable'),
344
+ search: state.get('searchable'),
345
+ filters: state.get('filterable'),
346
+ date: state.get('date'),
347
+ display: state.has('display') ? state.get('display') : state.get('displaySettings'),
348
+ dragInfo: state.get('dragInfo'),
349
+ idealColumnWidth: state.get('idealColumnWidth'),
350
+ suggestedWidth: state.get('suggestedWidth'),
351
+ suggestedHeight: state.get('suggestedHeight'),
352
+ AttachmentView: state.get('AttachmentView')
353
+ });
354
+
355
+ },
356
+
357
+ /**
358
+ * Removes the sidebar from the frame
359
+ */
360
+ removeSidebar: function(view) {
361
+
362
+ // Remove the sidebar
363
+ view.sidebar.remove('details');
364
+
365
+ // Hide sidebar altogether
366
+ view.$el.addClass('hide-sidebar');
367
+
368
+ },
369
+
370
+ /**
371
+ * Creates our states
372
+ */
373
+ createStates: function() {
374
+
375
+ // Add the default states
376
+ this.states.add([
377
+ new Admin.controller.AddSlide.image({
378
+ id: 'insert',
379
+ type: 'image',
380
+ title: _easingsliderAdminL10n.media_upload.image_from_media,
381
+ priority: 20,
382
+ toolbar: 'insert-slide',
383
+ filterable: false,
384
+ library: wp.media.query({ type: 'image' }),
385
+ multiple: true,
386
+ editable: true,
387
+ allowLocalEdits: true,
388
+ displaySettings: false,
389
+ displayUserSettings: true
390
+ })
391
+ ]);
392
+
393
+ },
394
+
395
+ /**
396
+ * We're overriding this method to prevent WordPress from adding iFrame states to our states.
397
+ * We don't want these, simple.
398
+ */
399
+ createIframeStates: function() {
400
+
401
+ return this;
402
+
403
+ },
404
+
405
+ /**
406
+ * Adds our "Insert into Slider" toolbar
407
+ */
408
+ insertToolbar: function(view) {
409
+
410
+ var controller = this;
411
+
412
+ // Add the toolbar to our provided view
413
+ view.set('insert-slide', {
414
+ style: 'primary',
415
+ priority: 80,
416
+ text: _easingsliderAdminL10n.media_upload.insert_into_slider,
417
+ requires: { selection: false },
418
+ click: function() {
419
+
420
+ // Close then trigger "insert", providing the selection
421
+ controller.close().trigger('insert', controller.getSelection()).reset();
422
+
423
+ }
424
+ });
425
+
426
+ },
427
+
428
+ /**
429
+ * Prepares & returns our selection for handoff to our view(s)
430
+ */
431
+ getSelection: function(selection) {
432
+
433
+ var collection = new wp.media.model.Selection(null, { multiple: true });
434
+
435
+ // Get the type & selection
436
+ var type = this.state().get('type'),
437
+ selection = this.state().get('selection');
438
+
439
+ // Loop through each selection
440
+ _.each(selection.models, function(model) {
441
+
442
+ // Create a new slide & set its type
443
+ var slide = new Admin.model.Slide.get({
444
+ type: type
445
+ });
446
+
447
+ // Handle attachments (attachments will have an ID attribute)
448
+ if ( model.get('id') ) {
449
+ slide.attachment = model;
450
+ slide.set({ attachment_id: model.get('id') }, { silent: true });
451
+ }
452
+ else {
453
+ slide.set(model, { silent: true });
454
+ }
455
+
456
+ // Add to the collection
457
+ collection.add(slide);
458
+
459
+ }, this);
460
+
461
+ return collection;
462
+
463
+ },
464
+
465
+ /**
466
+ * Updates the URL when the frame is closed
467
+ */
468
+ updateRouter: function() {
469
+
470
+ Admin.Router.navigate(_easingsliderAdminL10n.base_url);
471
+
472
+ }
473
+
474
+ });
475
+
476
+ /**
477
+ * Returns the appropriate "Edit Slide" controller
478
+ */
479
+ Admin.frame.EditSlide = {
480
+
481
+ /**
482
+ * Get the appropriate frame
483
+ */
484
+ get: function(options) {
485
+
486
+ if ( 'undefined' !== typeof Admin.frame.EditSlide[options.model.get('type')] ) {
487
+ return new Admin.frame.EditSlide[options.model.get('type')](options);
488
+ }
489
+
490
+ return new Admin.frame.EditSlide.base(options);
491
+
492
+ }
493
+
494
+ };
495
+
496
+ /**
497
+ * Base "Edit Slide" Frame
498
+ */
499
+ Admin.frame.EditSlide.base = wp.media.view.MediaFrame.Select.extend({
500
+
501
+ /**
502
+ * Classname
503
+ */
504
+ className: 'edit-slide-frame media-frame',
505
+
506
+ /**
507
+ * Template for this frame
508
+ */
509
+ template: wp.template('easingslider-edit-slide-frame'),
510
+
511
+ /**
512
+ * Events
513
+ */
514
+ events: _.defaults({
515
+ 'click .left': 'previousSlide',
516
+ 'click .right': 'nextSlide'
517
+ }, wp.media.view.MediaFrame.Select.prototype.events),
518
+
519
+ /**
520
+ * Constructor
521
+ */
522
+ initialize: function() {
523
+
524
+ // Set our options
525
+ this.options.state = 'edit-slide';
526
+ this.options.selection = new wp.media.model.Selection({}, { multiple: false });
527
+
528
+ // Call parent constructor
529
+ wp.media.view.MediaFrame.Select.prototype.initialize.apply(this, arguments);
530
+
531
+ },
532
+
533
+ /**
534
+ * Bind event handlers
535
+ */
536
+ bindHandlers: function() {
537
+
538
+ var frame = this;
539
+
540
+ // Bind events
541
+ this.on('close', this.updateRouter, this);
542
+ this.on('content:create:edit-slide', this.createView, this);
543
+ this.on('toolbar:render:edit-slide', this.createToolbar, this);
544
+
545
+ // Call parent
546
+ wp.media.view.MediaFrame.Select.prototype.bindHandlers.apply(this, arguments);
547
+
548
+ },
549
+
550
+ /**
551
+ * Creates the view
552
+ */
553
+ createView: function(options) {
554
+
555
+ // Initiate the view
556
+ options.view = new Admin.view.EditSlide.get({
557
+ type: this.model.get('type'),
558
+ model: this.model,
559
+ controller: this
560
+ });
561
+
562
+ },
563
+
564
+ /**
565
+ * Creates the toolbar
566
+ */
567
+ createToolbar: function() {
568
+
569
+ // Create and set the toolbar
570
+ this.toolbar.set(
571
+ new wp.media.view.Toolbar({
572
+ controller: this,
573
+ items: {
574
+ select: {
575
+ style: 'primary',
576
+ text: _easingsliderAdminL10n.media_upload.update,
577
+ priority: 80,
578
+ click: function() {
579
+
580
+ // Establish variables
581
+ var controller = this.controller,
582
+ state = controller.state();
583
+
584
+ // Close the frame
585
+ controller.close();
586
+
587
+ // Trigger update
588
+ state.trigger('update', controller.model.toJSON());
589
+
590
+ // Restore and reset the default state
591
+ controller.setState(controller.options.state);
592
+ controller.reset();
593
+
594
+ }
595
+ }
596
+ }
597
+ })
598
+ );
599
+
600
+ },
601
+
602
+ /**
603
+ * Creates our states
604
+ */
605
+ createStates: function() {
606
+
607
+ // Add our "Edit Slide" state
608
+ this.states.add([
609
+ new Admin.controller.EditSlide.get({
610
+ type: this.model.get('type')
611
+ })
612
+ ]);
613
+
614
+ // Call parent states
615
+ wp.media.view.MediaFrame.Select.prototype.createStates.apply(this, arguments);
616
+
617
+ },
618
+
619
+ /**
620
+ * Renders the frame
621
+ */
622
+ render: function() {
623
+
624
+ // Call parent
625
+ wp.media.view.MediaFrame.Select.prototype.render.apply(this, arguments);
626
+
627
+ // Toggle navigation
628
+ this.toggleNav();
629
+
630
+ return this;
631
+
632
+ },
633
+
634
+ /**
635
+ * Rerenders the frame
636
+ */
637
+ rerender: function() {
638
+
639
+ // Rerender the content region
640
+ this.content.render();
641
+
642
+ // Toggle navigation
643
+ this.toggleNav();
644
+
645
+ return this;
646
+
647
+ },
648
+
649
+ /**
650
+ * Toggles the navigation
651
+ */
652
+ toggleNav: function() {
653
+
654
+ // Reset navigation
655
+ this.$('.left').removeProp('disabled').removeClass('disabled');
656
+ this.$('.right').removeProp('disabled').removeClass('disabled');
657
+
658
+ // Toggle previous
659
+ if ( ! this.hasPrevious() ) {
660
+ this.$('.left').prop('disabled', 'disabled').addClass('disabled');
661
+ }
662
+
663
+ // Toggle next
664
+ if ( ! this.hasNext() ) {
665
+ this.$('.right').prop('disabled', 'disabled').addClass('disabled');
666
+ }
667
+
668
+ return this;
669
+
670
+ },
671
+
672
+ /**
673
+ * Click handler to switch to the previous slide
674
+ */
675
+ previousSlide: function() {
676
+
677
+ // Bail if we don't have a previous slide
678
+ if ( ! this.hasPrevious() ) {
679
+ this.$('.left').blur();
680
+ return;
681
+ }
682
+
683
+ // Set the new model
684
+ this.model = this.collection.at(this.collection.indexOf(this.model) - 1);
685
+
686
+ // Rerender the view
687
+ this.rerender();
688
+
689
+ // Focus navigation arrow
690
+ this.$('.left').focus();
691
+
692
+ },
693
+
694
+ /**
695
+ * Click handler to switch to the next slide
696
+ */
697
+ nextSlide: function() {
698
+
699
+ // Bail if we don't have a next slide
700
+ if ( ! this.hasNext() ) {
701
+ this.$('.right').blur();
702
+ return;
703
+ }
704
+
705
+ // Set the new model
706
+ this.model = this.collection.at(this.collection.indexOf(this.model) + 1);
707
+
708
+ // Rerender the view
709
+ this.rerender();
710
+
711
+ // Focus navigation arrow
712
+ this.$( '.right' ).focus();
713
+
714
+ },
715
+
716
+ /**
717
+ * Checks if we have a next slide
718
+ */
719
+ hasNext: function() {
720
+
721
+ return ( this.collection.indexOf(this.model) + 1 ) < this.collection.length;
722
+
723
+ },
724
+
725
+ /**
726
+ * Checks if we have a previous slide
727
+ */
728
+ hasPrevious: function() {
729
+
730
+ return ( this.collection.indexOf(this.model) - 1 ) > -1;
731
+
732
+ },
733
+
734
+ /**
735
+ * Updates the URL when the frame is closed
736
+ */
737
+ updateRouter: function() {
738
+
739
+ Admin.Router.navigate(_easingsliderAdminL10n.base_url);
740
+
741
+ }
742
+
743
+ });
744
+
745
+ /**
746
+ * Image "Edit Slide" Frame
747
+ */
748
+ Admin.frame.EditSlide.image = Admin.frame.EditSlide.base.extend({
749
+
750
+ /**
751
+ * Constructor
752
+ */
753
+ initialize: function() {
754
+
755
+ // Set the image
756
+ this.image = new wp.media.model.PostImage(this.model.attributes);
757
+
758
+ // Call parent constructor
759
+ Admin.frame.EditSlide.base.prototype.initialize.apply(this, arguments);
760
+
761
+ },
762
+
763
+ /**
764
+ * Bind event handlers
765
+ */
766
+ bindHandlers: function() {
767
+
768
+ // Bind events
769
+ this.on('content:create:browse', this.modifyBrowseFilters, this);
770
+ this.on('content:render:browse', this.removeBrowseSidebar, this);
771
+ this.on('content:render:edit-slide', this.showNav, this);
772
+ this.on('content:render:edit-image', this.renderEditImageContent, this);
773
+ this.on('toolbar:render:replace', this.hideNav, this);
774
+ this.on('toolbar:render:replace', this.renderReplaceImageToolbar, this);
775
+ this.state('replace-image').on('replace', this.replaceImage, this);
776
+
777
+ // Call parent
778
+ Admin.frame.EditSlide.base.prototype.bindHandlers.apply(this, arguments);
779
+
780
+ },
781
+
782
+ /**
783
+ * Create our states
784
+ */
785
+ createStates: function() {
786
+
787
+ // Call parent
788
+ Admin.frame.EditSlide.base.prototype.createStates.apply(this, arguments);
789
+
790
+ // Add "Edit" and "Replace" image states
791
+ this.states.add([
792
+ new wp.media.controller.ReplaceImage({
793
+ id: 'replace-image',
794
+ library: wp.media.query({ type: 'image' }),
795
+ image: this.image,
796
+ multiple: false,
797
+ title: _easingsliderAdminL10n.media_upload.replace_image,
798
+ toolbar: 'replace',
799
+ priority: 80,
800
+ displaySettings: true
801
+ }),
802
+ new wp.media.controller.EditImage( {
803
+ image: this.image,
804
+ selection: this.options.selection
805
+ } )
806
+ ]);
807
+
808
+ },
809
+
810
+ /**
811
+ * Overrides the Media Library browser filters, as the default filters aren't suitable.
812
+ */
813
+ modifyBrowseFilters: function(contentRegion) {
814
+
815
+ // Set the filters state
816
+ this.state().set('filterable', true);
817
+
818
+ },
819
+
820
+ /**
821
+ * Removes the sidebar from the Media Library browser
822
+ */
823
+ removeBrowseSidebar: function(view) {
824
+
825
+ // Remove the sidebar and hide it's element
826
+ view.sidebar.remove('details');
827
+ view.$el.addClass('hide-sidebar');
828
+
829
+ },
830
+
831
+ /**
832
+ * Show the navigation
833
+ */
834
+ showNav: function() {
835
+
836
+ this.$('.left, .right').show();
837
+ $('.media-modal-close').removeClass('no-border');
838
+
839
+ },
840
+
841
+ /**
842
+ * Hide the navigation
843
+ */
844
+ hideNav: function() {
845
+
846
+ this.$('.left, .right').hide();
847
+ $('.media-modal-close').addClass('no-border');
848
+
849
+ },
850
+
851
+ /**
852
+ * Renders the "Edit Image" view in the frame
853
+ */
854
+ renderEditImageContent: function() {
855
+
856
+ // Establish variables
857
+ var state = this.state(),
858
+ model = state.get('image'),
859
+ view;
860
+
861
+ // Bail if we have no model
862
+ if ( ! model ) {
863
+ return;
864
+ }
865
+
866
+ // Initiate the "Edit Image" view
867
+ view = new wp.media.view.EditImage({ model: model, controller: this }).render();
868
+
869
+ // Set the frame content
870
+ this.content.set(view);
871
+
872
+ // After bringing in the frame, load the actual editor via an ajax call
873
+ view.loadEditor();
874
+
875
+ },
876
+
877
+ /**
878
+ * Renders the "Replace Image" toolbar in the frame
879
+ */
880
+ renderReplaceImageToolbar: function() {
881
+
882
+ // Establish variables
883
+ var frame = this,
884
+ lastState = frame.lastState(),
885
+ previous = lastState && lastState.id;
886
+
887
+ // Set the toolbar
888
+ this.toolbar.set(
889
+ new wp.media.view.Toolbar({
890
+ controller: this,
891
+ items: {
892
+ back: {
893
+ text: _easingsliderAdminL10n.media_upload.back,
894
+ priority: 20,
895
+ click: function() {
896
+
897
+ // Close or go back to previous state
898
+ if ( previous ) {
899
+ frame.setState(previous);
900
+ } else {
901
+ frame.close();
902
+ }
903
+
904
+ }
905
+ },
906
+ replace: {
907
+ style: 'primary',
908
+ text: _easingsliderAdminL10n.media_upload.replace,
909
+ priority: 80,
910
+ click: function() {
911
+
912
+ // Establish variables
913
+ var controller = this.controller,
914
+ state = controller.state(),
915
+ selection = state.get('selection'),
916
+ attachment = selection.single();
917
+
918
+ // Close controller
919
+ controller.close();
920
+
921
+ // Change attachment
922
+ controller.image.changeAttachment(attachment, state.display(attachment));
923
+
924
+ // Not sure if we want to use wp.media.string.image which will create a shortcode or
925
+ // perhaps wp.html.string to at least to build the <img />
926
+ state.trigger( 'replace', controller.image.toJSON() );
927
+
928
+ // Restore and reset the default state
929
+ controller.setState(controller.options.state);
930
+ controller.reset();
931
+
932
+ }
933
+ }
934
+ }
935
+ })
936
+ );
937
+
938
+ },
939
+
940
+ /**
941
+ * Replaces the image
942
+ *
943
+ * This functionality is only available to attachment,
944
+ * so we can safely assume this is one.
945
+ */
946
+ replaceImage: function() {
947
+
948
+ // Replace the attachment
949
+ this.model.set({ attachment_id: this.image.attachment.id });
950
+ this.model.attachment.set(this.image.attachment.attributes);
951
+
952
+ }
953
+
954
+ });
955
+
956
+ /**
957
+ * "Editor" View
958
+ */
959
+ Admin.view.Editor = Backbone.View.extend({
960
+
961
+ /**
962
+ * Our view element
963
+ */
964
+ el: '.wrap',
965
+
966
+ /**
967
+ * Events
968
+ */
969
+ events: {
970
+ 'click #add-slides': '_addSlide',
971
+ 'click #select-all': '_selectAll',
972
+ 'click #delete-slides': '_clickBulkDelete',
973
+ 'click #save': '_clickSave',
974
+ 'click .toolbar .edit': '_clickEdit',
975
+ 'click .toolbar .remove': '_clickDelete',
976
+ 'click .show-advanced-options': '_clickAdvancedOptions',
977
+ 'click .thumbnail': '_clickThumb',
978
+ 'click .select-mode-toggle-button': '_toggleMode',
979
+ 'click .sidebar-name': '_toggleWidget'
980
+ },
981
+
982
+ /**
983
+ * Constructor
984
+ */
985
+ initialize: function() {
986
+
987
+ // Initiate our subviews
988
+ this.subviews = {
989
+ AddSlide: new Admin.frame.AddSlide(),
990
+ Slides: new Admin.view.Slides({
991
+ collection: this.collection
992
+ })
993
+ };
994
+
995
+ // Bind our events
996
+ this.collection.on('sync:done', this.render, this);
997
+ this.collection.on('sync:done', this._enableSave, this);
998
+ this.collection.on('sync:done', this._handleNoSlides, this);
999
+ this.collection.on('add', this._handleNoSlides, this);
1000
+ this.collection.on('remove', this._handleNoSlides, this);
1001
+ this.subviews.AddSlide.on('insert', this._handleInsert, this);
1002
+
1003
+ // Change number of columns on window resize
1004
+ $(window).on('resize', this._setColumns.bind(this));
1005
+
1006
+ // Disable select mode
1007
+ this._selectMode = false;
1008
+
1009
+ // Set number of columns
1010
+ this._setColumns();
1011
+
1012
+ // Show the spinner
1013
+ this._showSpinner();
1014
+
1015
+ },
1016
+
1017
+ /**
1018
+ * Shows the spinner
1019
+ */
1020
+ _showSpinner: function() {
1021
+
1022
+ this.$('#slides-browser').append('<div class="spinner"></div>');
1023
+
1024
+ },
1025
+
1026
+ /**
1027
+ * Hides the spinner
1028
+ */
1029
+ _hideSpinner: function() {
1030
+
1031
+ this.$('#slides-browser .spinner').remove();
1032
+
1033
+ },
1034
+
1035
+ /**
1036
+ * Enables the save button
1037
+ */
1038
+ _enableSave: function() {
1039
+
1040
+ this.$('#save').prop('disabled', false);
1041
+
1042
+ },
1043
+
1044
+ /**
1045
+ * Handles save button click
1046
+ */
1047
+ _clickSave: function() {
1048
+
1049
+ this.$('#publishing-action .spinner').css({ 'display': 'block' });
1050
+
1051
+ },
1052
+
1053
+ /**
1054
+ * Sets the appropriate number of columns
1055
+ */
1056
+ _setColumns: function() {
1057
+
1058
+ var content = this.$('.media-frame-content'),
1059
+ previous_columns = content.attr('data-columns'),
1060
+ width = content.width();
1061
+
1062
+ // Continue if we have width
1063
+ if ( width ) {
1064
+
1065
+ // Calculate the maximum number of columns we can fit
1066
+ var columns = Math.min(Math.round(width / 145), 12) || 1;
1067
+
1068
+ // Change the number of columns if it's not the same as previously
1069
+ if ( ! previous_columns || previous_columns !== columns ) {
1070
+ content.attr('data-columns', columns);
1071
+ }
1072
+
1073
+ }
1074
+
1075
+ },
1076
+
1077
+ /**
1078
+ * Handles our slides hidden input when no slides exists
1079
+ */
1080
+ _handleNoSlides: function() {
1081
+
1082
+ if ( 0 == this.collection.length ) {
1083
+ this.$('form').prepend('<input type="hidden" id="slides" name="slides" value="[]" />');
1084
+ }
1085
+ else {
1086
+ this.$('input[name="slides"]').remove();
1087
+ }
1088
+
1089
+ },
1090
+
1091
+ /**
1092
+ * Handles slide(s) insert from the "Add Slide" frame view
1093
+ */
1094
+ _handleInsert: function(selection) {
1095
+
1096
+ // Add to the collection
1097
+ this.collection.add(selection.models);
1098
+
1099
+ },
1100
+
1101
+ /**
1102
+ * Handles a thumbnail click event
1103
+ */
1104
+ _clickThumb: function(event) {
1105
+
1106
+ event.preventDefault();
1107
+
1108
+ // Handle click based on mode
1109
+ if ( ! this._selectMode ) {
1110
+ this._editSlide(event);
1111
+ }
1112
+ else {
1113
+ this._toggleSelect(event);
1114
+ }
1115
+
1116
+ },
1117
+
1118
+ /**
1119
+ * Handles an "edit" button click event
1120
+ */
1121
+ _clickEdit: function(event) {
1122
+
1123
+ event.preventDefault();
1124
+
1125
+ this._editSlide(event);
1126
+
1127
+ },
1128
+
1129
+ /**
1130
+ * Handles a "delete" button click event
1131
+ */
1132
+ _clickDelete: function(event) {
1133
+
1134
+ event.preventDefault();
1135
+
1136
+ if ( confirm( _easingsliderAdminL10n.warn ) ) {
1137
+
1138
+ // Get the model ID
1139
+ var id = $(event.currentTarget).parents('.attachment').attr('data-id');
1140
+
1141
+ // Delete the model from the collection
1142
+ this.collection.remove(id);
1143
+
1144
+ }
1145
+
1146
+ },
1147
+
1148
+ /**
1149
+ * Handles a bulk delete button click
1150
+ */
1151
+ _clickBulkDelete: function(event) {
1152
+
1153
+ event.preventDefault();
1154
+
1155
+ if ( confirm( _easingsliderAdminL10n.warn ) ) {
1156
+
1157
+ // Delete the slides
1158
+ this._deleteSlides(event);
1159
+
1160
+ // Toggle mode
1161
+ this._toggleMode(event);
1162
+
1163
+ }
1164
+
1165
+ },
1166
+
1167
+ /**
1168
+ * Handles "advanced options" link click
1169
+ */
1170
+ _clickAdvancedOptions: function(event) {
1171
+
1172
+ event.preventDefault();
1173
+
1174
+ // Get the advanced options
1175
+ var $options = $(event.currentTarget).parent().find('.advanced-options');
1176
+
1177
+ // Find the closest advanced options and show it
1178
+ $options.toggleClass('hide');
1179
+
1180
+ },
1181
+
1182
+ /**
1183
+ * Toggles between "Bulk Select" mode
1184
+ */
1185
+ _toggleMode: function(event) {
1186
+
1187
+ event.preventDefault();
1188
+
1189
+ // Toggle mode
1190
+ if ( ! this._selectMode ) {
1191
+ this._selectMode = true;
1192
+ }
1193
+ else {
1194
+ this._selectMode = false;
1195
+ }
1196
+
1197
+ // Toggle select mode class
1198
+ this.$('.attachment').removeClass('selected details');
1199
+ this.$('.media-frame').toggleClass('mode-select');
1200
+ this.$('.media-toolbar div *').toggleClass('hide');
1201
+
1202
+ },
1203
+
1204
+ /**
1205
+ * Toggles selection of a slide on click
1206
+ */
1207
+ _toggleSelect: function(event) {
1208
+
1209
+ event.preventDefault()
1210
+
1211
+ // Highlight the thumbnail
1212
+ $(event.currentTarget).parents('.attachment').toggleClass('selected details');
1213
+
1214
+ },
1215
+
1216
+ /**
1217
+ * Toggles a sidebar settings widget metabox
1218
+ */
1219
+ _toggleWidget: function(event) {
1220
+
1221
+ event.preventDefault();
1222
+
1223
+ var $widget = $(event.currentTarget).parent(),
1224
+ $content = $widget.find('.sidebar-content');
1225
+
1226
+ // Bail if this is a fixed widget
1227
+ if ( $widget.hasClass('fixed') ) {
1228
+ return;
1229
+ }
1230
+
1231
+ // Close any open sidebar metaboxes
1232
+ this.$('.widgets-holder-wrap').each(function() {
1233
+ var $metabox = $(this);
1234
+
1235
+ if ( ! $metabox.hasClass('fixed') ) {
1236
+ $metabox.find('.sidebar-content').slideUp(200, function() {
1237
+ $metabox.addClass('closed');
1238
+ });
1239
+ }
1240
+ });
1241
+
1242
+ // Bail if the clicked widget is already open
1243
+ if ( ! $widget.hasClass('closed') ) {
1244
+ return;
1245
+ }
1246
+
1247
+ // Open the sidebar metabox
1248
+ $content.slideDown(200, function() {
1249
+ $widget.removeClass('closed');
1250
+ });
1251
+
1252
+ },
1253
+
1254
+ /**
1255
+ * Selects all of the slides
1256
+ */
1257
+ _selectAll: function(event) {
1258
+
1259
+ event.preventDefault();
1260
+
1261
+ // Highlight all the thumbnails
1262
+ this.$('.attachment').addClass('selected details');
1263
+
1264
+ },
1265
+
1266
+ /**
1267
+ * Deletes the currently selected slides
1268
+ */
1269
+ _deleteSlides: function(event) {
1270
+
1271
+ event.preventDefault();
1272
+
1273
+ // Establish variables
1274
+ var collection = this.collection,
1275
+ models = [];
1276
+
1277
+ // Loop through each slide and remove selected
1278
+ this.$('.attachment').each(function(index) {
1279
+
1280
+ // Check if this slide has been selected & add it to be removed if so.
1281
+ if ( $(this).hasClass('selected') ) {
1282
+ models.push(collection.at(index));
1283
+ }
1284
+
1285
+ });
1286
+
1287
+ // Remove the models from the collection
1288
+ this.collection.remove(models);
1289
+
1290
+ },
1291
+
1292
+ /**
1293
+ * Opens the "Add Slide" frame view on click
1294
+ */
1295
+ _addSlide: function(event) {
1296
+
1297
+ event.preventDefault();
1298
+
1299
+ // Open the frame
1300
+ this.addSlide();
1301
+
1302
+ // Navigate router
1303
+ Admin.Router.navigate(_easingsliderAdminL10n.base_url + '&add=true');
1304
+
1305
+ },
1306
+
1307
+ /**
1308
+ * Opens the "Add Slide" frame
1309
+ */
1310
+ addSlide: function() {
1311
+
1312
+ // Open the "Add Slide" frame
1313
+ this.subviews.AddSlide.open();
1314
+
1315
+ return this;
1316
+
1317
+ },
1318
+
1319
+ /**
1320
+ * Opens the "Edit Slide" frame on click
1321
+ */
1322
+ _editSlide: function(event) {
1323
+
1324
+ event.preventDefault();
1325
+
1326
+ // Get the slide ID
1327
+ var id = $(event.currentTarget).parents('.attachment').attr('data-id');
1328
+
1329
+ // Open the frame
1330
+ this.editSlide(id);
1331
+
1332
+ // Navigate router
1333
+ Admin.Router.navigate(_easingsliderAdminL10n.base_url + '&slide=' + id);
1334
+
1335
+ },
1336
+
1337
+ /**
1338
+ * Opens the "Edit Slide" frame
1339
+ */
1340
+ editSlide: function(id) {
1341
+
1342
+ // Create the frame
1343
+ this.subviews.EditSlide = new Admin.frame.EditSlide.get({
1344
+ collection: this.collection,
1345
+ model: this.collection.get(id)
1346
+ });
1347
+
1348
+ // Open the frame
1349
+ this.subviews.EditSlide.open();
1350
+
1351
+ return this;
1352
+
1353
+ },
1354
+
1355
+ /**
1356
+ * Adds a frame to "Add Slide"
1357
+ */
1358
+ newAddSlideFrame: function(options) {
1359
+
1360
+ var frame = this.subviews.AddSlide;
1361
+
1362
+ // Add our states to the "Add Slide" frame
1363
+ frame.states.add([
1364
+ new Admin.controller.AddSlide.get(options)
1365
+ ]);
1366
+
1367
+ // Render content
1368
+ frame.on('content:render:'+ options.content, function() {
1369
+
1370
+ // Create the view
1371
+ var view = new Admin.view.AddSlide.get({
1372
+ type: options.content,
1373
+ model: this.state().props,
1374
+ controller: this
1375
+ });
1376
+
1377
+ // Set the view
1378
+ this.content.set(view);
1379
+
1380
+ }, frame);
1381
+
1382
+ // Render toolbar
1383
+ frame.on('toolbar:render:'+ options.toolbar, function() {
1384
+
1385
+ // Create the toolbar
1386
+ var toolbar = new Admin.toolbar.AddSlide.get({
1387
+ type: options.toolbar,
1388
+ controller: this
1389
+ });
1390
+
1391
+ // Set the toolbar
1392
+ this.toolbar.set(toolbar);
1393
+
1394
+ }, frame);
1395
+
1396
+ },
1397
+
1398
+ /**
1399
+ * Renders the view
1400
+ */
1401
+ render: function() {
1402
+
1403
+ // Hide the spinner
1404
+ this._hideSpinner();
1405
+
1406
+ // Render the subview
1407
+ var slides = this.subviews.Slides.render().el;
1408
+
1409
+ // Add the slides to the view
1410
+ this.$('#slides-browser').append(slides);
1411
+
1412
+ return this;
1413
+
1414
+ }
1415
+
1416
+ });
1417
+
1418
+ /**
1419
+ * "Slides" View
1420
+ */
1421
+ Admin.view.Slides = Backbone.View.extend({
1422
+
1423
+ /**
1424
+ * Tagname
1425
+ */
1426
+ tagName: 'ul',
1427
+
1428
+ /**
1429
+ * Attributes
1430
+ */
1431
+ attributes: {
1432
+ 'class': 'attachments ui-sortable',
1433
+ 'tabindex': '-1'
1434
+ },
1435
+
1436
+ /**
1437
+ * Constructor
1438
+ */
1439
+ initialize: function() {
1440
+
1441
+ // Subviews
1442
+ this.subviews = [];
1443
+
1444
+ // Bind our collection events
1445
+ this.collection.on('add', this.add, this);
1446
+ this.collection.on('remove', this.render, this);
1447
+ this.collection.on('reset', this.render, this);
1448
+
1449
+ // Enable sorting
1450
+ this.$el.sortable({
1451
+ items: '.attachment',
1452
+ containment: 'parent',
1453
+ tolerance: 'pointer',
1454
+ stop: this._sort.bind(this)
1455
+ });
1456
+
1457
+ },
1458
+
1459
+ /**
1460
+ * Sorts the view
1461
+ */
1462
+ _sort: function(event, ui) {
1463
+
1464
+ // Get the model
1465
+ var model = this.collection.get(ui.item.context.dataset.id);
1466
+
1467
+ // Reposition the model in the collection
1468
+ this.collection.reposition(model, ui.item.index());
1469
+
1470
+ },
1471
+
1472
+ /**
1473
+ * Adds a subview
1474
+ */
1475
+ add: function(model) {
1476
+
1477
+ // Render and add the slide to the view
1478
+ var view = new Admin.view.Slide({
1479
+ model: model
1480
+ });
1481
+
1482
+ // Add the subview
1483
+ this.subviews.push(view);
1484
+
1485
+ // Render and append subview to this view
1486
+ this.$el.append(view.render().$el);
1487
+
1488
+ return this;
1489
+
1490
+ },
1491
+
1492
+ /**
1493
+ * Renders the view
1494
+ */
1495
+ render: function() {
1496
+
1497
+ this.subviews = [];
1498
+
1499
+ // Empty the view
1500
+ this.$el.empty();
1501
+
1502
+ // Render each subview
1503
+ _.each(this.collection.models, function(model) {
1504
+ this.add(model);
1505
+ }, this);
1506
+
1507
+ return this;
1508
+
1509
+ }
1510
+
1511
+ });
1512
+
1513
+ /**
1514
+ * "Slide" View
1515
+ */
1516
+ Admin.view.Slide = Backbone.View.extend({
1517
+
1518
+ /**
1519
+ * Tagname
1520
+ */
1521
+ tagName: 'li',
1522
+
1523
+ /**
1524
+ * Attributes
1525
+ */
1526
+ attributes: function() {
1527
+ return {
1528
+ 'role': 'checkbox',
1529
+ 'class': 'attachment save-ready',
1530
+ 'tabindex': '0',
1531
+ 'data-id': this.model.id
1532
+ };
1533
+ },
1534
+
1535
+ /**
1536
+ * Template for this view
1537
+ */
1538
+ template: wp.media.template('easingslider-slide'),
1539
+
1540
+ /**
1541
+ * Constructor
1542
+ */
1543
+ initialize: function() {
1544
+
1545
+ // Bind events
1546
+ this.model.on('change', this._setData, this);
1547
+ this.model.on('change:id', this._updateID, this);
1548
+ this.model.on('change:url', this.render, this);
1549
+ this.model.on('change:poster', this.render, this);
1550
+ this.model.on('change:attachment_id', this.render, this);
1551
+
1552
+ // Bind additional attachment events if appropriate
1553
+ if ( this.model.attachment ) {
1554
+ this.model.attachment.on('change', this.render, this);
1555
+ }
1556
+
1557
+ },
1558
+
1559
+ /**
1560
+ * Sets our data
1561
+ */
1562
+ _setData: function() {
1563
+
1564
+ // Set data in hidden input
1565
+ this.$('input[name="slides[]"]').val(JSON.stringify(this.model.attributes));
1566
+
1567
+ },
1568
+
1569
+ /**
1570
+ * Update our ID attribute
1571
+ */
1572
+ _updateID: function(model, value) {
1573
+
1574
+ // Update attrbitue on DOM
1575
+ this.$el.attr('data-id', value);
1576
+
1577
+ // Update attribute on view object
1578
+ this.attributes['data-id'] = value;
1579
+
1580
+ },
1581
+
1582
+ /**
1583
+ * Renders the view
1584
+ */
1585
+ render: function() {
1586
+
1587
+ var data = { model: this.model.toJSON() };
1588
+
1589
+ // If our model has an attachment, add it to the data.
1590
+ if ( this.model.attachment ) {
1591
+ data.attachment = this.model.attachment.toJSON();
1592
+ }
1593
+
1594
+ // Generate the template
1595
+ this.$el.html(this.template(data));
1596
+
1597
+ return this;
1598
+
1599
+ }
1600
+
1601
+ });
1602
+
1603
+ /**
1604
+ * Returns the appropriate "Add Slide" view
1605
+ */
1606
+ Admin.view.AddSlide = {
1607
+
1608
+ /**
1609
+ * Get the appropriate view
1610
+ */
1611
+ get: function(options) {
1612
+
1613
+ if ( 'undefined' !== typeof Admin.view.AddSlide[options.type] ) {
1614
+ return new Admin.view.AddSlide[options.type](options);
1615
+ }
1616
+
1617
+ return new Admin.view.AddSlide.base(options);
1618
+
1619
+ }
1620
+
1621
+ };
1622
+
1623
+ /**
1624
+ * Base "Add Slide" View
1625
+ */
1626
+ Admin.view.AddSlide.base = wp.media.View.extend();
1627
+
1628
+ /**
1629
+ * Image "Add Slide" View
1630
+ */
1631
+ Admin.view.AddSlide.image = wp.media.view.AttachmentsBrowser.extend();
1632
+
1633
+ /**
1634
+ * Returns the appropriate "Edit Slide" view
1635
+ */
1636
+ Admin.view.EditSlide = {
1637
+
1638
+ /**
1639
+ * Get the appropriate view
1640
+ */
1641
+ get: function(options) {
1642
+
1643
+ if ( 'undefined' !== typeof Admin.view.EditSlide[options.type] ) {
1644
+ return new Admin.view.EditSlide[options.type](options);
1645
+ }
1646
+
1647
+ return new Admin.view.EditSlide.base(options);
1648
+
1649
+ }
1650
+
1651
+ };
1652
+
1653
+ /**
1654
+ * Base "Edit Slide" View
1655
+ */
1656
+ Admin.view.EditSlide.base = wp.media.view.Settings.extend({
1657
+
1658
+ /**
1659
+ * Classname
1660
+ */
1661
+ className: 'edit-attachment-frame attachment-details mode-select',
1662
+
1663
+ /**
1664
+ * Template for this view
1665
+ */
1666
+ template: wp.media.template('easingslider-edit-slide'),
1667
+
1668
+ /**
1669
+ * Constructor
1670
+ */
1671
+ initialize: function() {
1672
+
1673
+ // Call parent constructor
1674
+ wp.media.view.Settings.prototype.initialize.apply(this, arguments);
1675
+
1676
+ // Bind events
1677
+ this.model.on('change:link', this.toggleLinkSettings, this);
1678
+ this.model.on('change:link', this.updateLinkTo, this);
1679
+
1680
+ },
1681
+
1682
+ /**
1683
+ * Prepares the view data
1684
+ */
1685
+ prepare: function() {
1686
+
1687
+ var attachment = false;
1688
+
1689
+ // Check model for attachment
1690
+ if ( this.model.attachment ) {
1691
+ attachment = this.model.attachment.toJSON();
1692
+ }
1693
+
1694
+ return _.defaults({
1695
+ model: this.model.toJSON(),
1696
+ attachment: attachment
1697
+ }, this.options );
1698
+
1699
+ },
1700
+
1701
+ /**
1702
+ * Adds support for "Link" options show/hide
1703
+ */
1704
+ toggleLinkSettings: function() {
1705
+
1706
+ if ( 'none' === this.model.get('link') ) {
1707
+ this.$('.link-options').addClass('hide');
1708
+ } else {
1709
+ this.$('.link-options').removeClass('hide');
1710
+ }
1711
+
1712
+ },
1713
+
1714
+ /**
1715
+ * Handles "Link To" option
1716
+ */
1717
+ updateLinkTo: function() {
1718
+
1719
+ var linkTo = this.model.get('link'),
1720
+ $input = this.$('.link-to-custom');
1721
+
1722
+ if ( this.model.attachment ) {
1723
+
1724
+ if ( 'none' === linkTo || 'embed' === linkTo || ( ! this.model.attachment && 'custom' !== linkTo ) ) {
1725
+ $input.addClass('hidden');
1726
+ return;
1727
+ }
1728
+
1729
+ if ( this.model.attachment ) {
1730
+ if ( 'post' === linkTo ) {
1731
+ $input.val(this.model.attachment.get('link'));
1732
+ } else if ( 'file' === linkTo ) {
1733
+ $input.val(this.model.attachment.get('url'));
1734
+ } else if ( ! this.model.get('linkUrl') ) {
1735
+ $input.val('http://');
1736
+ }
1737
+
1738
+ $input.prop('readonly', 'custom' !== linkTo);
1739
+ }
1740
+
1741
+ $input.removeClass('hidden');
1742
+
1743
+ // If the input is visible, focus and select its contents.
1744
+ if ( ! wp.media.isTouchDevice && $input.is(':visible') ) {
1745
+ $input.focus()[0].select();
1746
+ }
1747
+
1748
+ }
1749
+
1750
+ },
1751
+
1752
+ /**
1753
+ * Renders the view
1754
+ */
1755
+ render: function() {
1756
+
1757
+ // Call parent
1758
+ wp.media.view.Settings.prototype.render.apply(this, arguments);
1759
+
1760
+ // Set toggles
1761
+ this.toggleLinkSettings();
1762
+ this.updateLinkTo();
1763
+
1764
+ return this;
1765
+
1766
+ }
1767
+
1768
+ });
1769
+
1770
+ /**
1771
+ * Image "Edit Slide" View
1772
+ */
1773
+ Admin.view.EditSlide.image = Admin.view.EditSlide.base.extend({
1774
+
1775
+ /**
1776
+ * Events
1777
+ */
1778
+ events: _.defaults({
1779
+ 'click .edit-attachment': 'editAttachment',
1780
+ 'click .replace-attachment': 'replaceAttachment'
1781
+ }, Admin.view.EditSlide.base.prototype.events),
1782
+
1783
+ /**
1784
+ * Constructor
1785
+ */
1786
+ initialize: function() {
1787
+
1788
+ // Call parent constructor
1789
+ Admin.view.EditSlide.base.prototype.initialize.apply(this, arguments);
1790
+
1791
+ // Bind events
1792
+ this.model.on('change:url', this.updateImage, this);
1793
+
1794
+ },
1795
+
1796
+ /**
1797
+ * Changes to "Edit" state
1798
+ */
1799
+ editAttachment: function(event) {
1800
+
1801
+ // Get current state
1802
+ var editState = this.controller.states.get('edit-image');
1803
+
1804
+ // Continue if editing is allowed and we've an edit state
1805
+ if ( window.imageEdit && editState ) {
1806
+ event.preventDefault();
1807
+ editState.set('image', this.model.attachment);
1808
+ this.controller.setState('edit-image');
1809
+ }
1810
+
1811
+ },
1812
+
1813
+ /**
1814
+ * Changes to "Replace" state
1815
+ */
1816
+ replaceAttachment: function(event) {
1817
+
1818
+ event.preventDefault();
1819
+
1820
+ this.controller.setState('replace-image');
1821
+
1822
+ },
1823
+
1824
+ /**
1825
+ * Updates the image preview (URL images only)
1826
+ */
1827
+ updateImage: function() {
1828
+
1829
+ this.$('.details-image').attr('src', this.model.get('url'));
1830
+
1831
+ }
1832
+
1833
+ });
1834
+
1835
+ /**
1836
+ * Returns the appropriate "Add Slide" toolbar
1837
+ */
1838
+ Admin.toolbar.AddSlide = {
1839
+
1840
+ /**
1841
+ * Get the appropriate toolbar
1842
+ */
1843
+ get: function(options) {
1844
+
1845
+ if ( 'undefined' !== typeof Admin.toolbar.AddSlide[options.type] ) {
1846
+ return new Admin.toolbar.AddSlide[options.type](options);
1847
+ }
1848
+
1849
+ return new Admin.toolbar.AddSlide.base(options);
1850
+
1851
+ }
1852
+
1853
+ };
1854
+
1855
+ /**
1856
+ * Base "Add Slide" Toolbar
1857
+ */
1858
+ Admin.toolbar.AddSlide.base = wp.media.view.Toolbar.extend();
1859
+
1860
+ /**
1861
+ * Router
1862
+ */
1863
+ Admin.router = Backbone.Router.extend({
1864
+
1865
+ /**
1866
+ * Routes
1867
+ */
1868
+ routes: {
1869
+ 'admin.php?page=:page&edit=:id&slide=:slide': 'editSlide',
1870
+ 'admin.php?page=:page&edit=:id&add=true': 'addSlide',
1871
+ 'admin.php?page=:page&edit=:id': 'editor',
1872
+ 'admin.php?page=easingslider-add-new': 'editor'
1873
+ },
1874
+
1875
+ /**
1876
+ * Constructor
1877
+ */
1878
+ initialize: function() {
1879
+
1880
+ // Get the slides
1881
+ var slides = ( typeof window.slides === 'undefined' ) ? '[]' : window.slides;
1882
+
1883
+ // Initate our view
1884
+ this.view = new Admin.view.Editor({
1885
+ collection: new Admin.collection.Slides(JSON.parse(slides))
1886
+ });
1887
+
1888
+ },
1889
+
1890
+ /**
1891
+ * Shows the "Edit Slide" frame
1892
+ */
1893
+ editSlide: function(page, id, slide) {
1894
+
1895
+ // Load the admin editor
1896
+ this.editor();
1897
+
1898
+ // Once the colleciton has been synced, open the edit slide frame
1899
+ this.view.collection.on('sync:done', function() {
1900
+ this.view.editSlide(slide);
1901
+ }, this);
1902
+
1903
+ return this;
1904
+
1905
+ },
1906
+
1907
+ /**
1908
+ * Shows the "Add Slide" frame
1909
+ */
1910
+ addSlide: function(page, id) {
1911
+
1912
+ // Load the admin editor
1913
+ this.editor();
1914
+
1915
+ // Once the colleciton has been synced, open the add slide frame
1916
+ this.view.collection.on('sync:done', function() {
1917
+ this.view.addSlide();
1918
+ }, this);
1919
+
1920
+ return this;
1921
+
1922
+ },
1923
+
1924
+ /**
1925
+ * Shows the admin editor
1926
+ */
1927
+ editor: function(page) {
1928
+
1929
+ // Sync the collection & get the ball rolling!
1930
+ this.view.collection.sync();
1931
+
1932
+ return this;
1933
+
1934
+ }
1935
+
1936
+ });
1937
+
1938
+ /**
1939
+ * Let's go!
1940
+ */
1941
+ $(document).ready(function() {
1942
+
1943
+ // Initiate the router
1944
+ Admin.Router = new Admin.router();
1945
+
1946
+ // Start the history
1947
+ Backbone.history.start({
1948
+ root: window._easingsliderAdminL10n.admin_url,
1949
+ pushState: true,
1950
+ });
1951
+
1952
+ // Handly delete class
1953
+ $('.delete').each(function() {
1954
+ $(this).on('click', function() {
1955
+ if ( ! confirm( _easingsliderAdminL10n.warn ) ) {
1956
+ return false;
1957
+ }
1958
+ });
1959
+ });
1960
+
1961
+ // Change our slider type
1962
+ $('select[name="type"]').on('change', function() {
1963
+
1964
+ // Hide options
1965
+ $('*[data-type]').addClass('hidden');
1966
+ $('*[data-type="'+ this.value +'"]').removeClass('hidden');
1967
+
1968
+ // Hide primary toolbar when not using slides from "Media"
1969
+ if ( 'media' != this.value ) {
1970
+ $('.media-toolbar-primary').addClass('hidden');
1971
+ } else {
1972
+ $('.media-toolbar-primary').removeClass('hidden');
1973
+ }
1974
+
1975
+ });
1976
+
1977
+ /**
1978
+ * Handle addon activation
1979
+ */
1980
+ $(document).on('click', '.js-activate-addon', function(event) {
1981
+ event.preventDefault();
1982
+
1983
+ // Establish variables
1984
+ var $button = $(this);
1985
+ var $el = $button.parents('.addon-status');
1986
+ var $message = $el.find('.status-message');
1987
+
1988
+ // Remove errors
1989
+ $('.action-error').remove();
1990
+
1991
+ // Tell the user what's happening
1992
+ $button.text(_easingsliderAdminL10n.buttons.activating);
1993
+
1994
+ // Process the Ajax to perform the activation.
1995
+ var options = {
1996
+ url: ajaxurl,
1997
+ type: 'post',
1998
+ async: true,
1999
+ cache: false,
2000
+ dataType: 'json',
2001
+ data: {
2002
+ action: 'easingslider_activate_addon',
2003
+ nonce: _easingsliderAdminL10n.nonces.activate,
2004
+ plugin: $button.attr('data-plugin')
2005
+ },
2006
+ success: function(response) {
2007
+
2008
+ // If there is a WP Error instance, output it here and quit
2009
+ if ( response && true !== response ) {
2010
+ $button.after('<div class="action-error error"><strong>'+ response.error +'</strong></div>');
2011
+ return false;
2012
+ }
2013
+
2014
+ // The Ajax request was successful, update the button.
2015
+ $button
2016
+ .text(_easingsliderAdminL10n.buttons.deactivate)
2017
+ .removeClass('js-activate-addon')
2018
+ .addClass('js-deactivate-addon');
2019
+
2020
+ // Update message
2021
+ $message.text(_easingsliderAdminL10n.messages.active);
2022
+
2023
+ // Change status
2024
+ $el.removeClass('is-inactive').addClass('is-active');
2025
+
2026
+ },
2027
+ error: function(xhr, textStatus, event) {
2028
+ return false;
2029
+ }
2030
+ };
2031
+
2032
+ // Perform ajax request
2033
+ $.ajax(options);
2034
+ });
2035
+
2036
+ /**
2037
+ * Handle addon deactivation
2038
+ */
2039
+ $(document).on('click', '.js-deactivate-addon', function(event) {
2040
+ event.preventDefault();
2041
+
2042
+ // Establish variables
2043
+ var $button = $(this);
2044
+ var $el = $button.parents('.addon-status');
2045
+ var $message = $el.find('.status-message');
2046
+
2047
+ // Remove errors
2048
+ $('.action-error').remove();
2049
+
2050
+ // Tell the user what's happening
2051
+ $button.text(_easingsliderAdminL10n.buttons.deactivating);
2052
+
2053
+ // Process the Ajax to perform the activation.
2054
+ var options = {
2055
+ url: ajaxurl,
2056
+ type: 'post',
2057
+ async: true,
2058
+ cache: false,
2059
+ dataType: 'json',
2060
+ data: {
2061
+ action: 'easingslider_deactivate_addon',
2062
+ nonce: _easingsliderAdminL10n.nonces.deactivate,
2063
+ plugin: $button.attr('data-plugin')
2064
+ },
2065
+ success: function(response) {
2066
+
2067
+ // If there is a WP Error instance, output it here and quit
2068
+ if ( response && true !== response ) {
2069
+ $button.after('<div class="action-error error"><strong>'+ response.error +'</strong></div>');
2070
+ return false;
2071
+ }
2072
+
2073
+ // The Ajax request was successful, update the button.
2074
+ $button
2075
+ .text(_easingsliderAdminL10n.buttons.activate)
2076
+ .removeClass('js-deactivate-addon')
2077
+ .addClass('js-activate-addon');
2078
+
2079
+ // Update message
2080
+ $message.text(_easingsliderAdminL10n.messages.inactive);
2081
+
2082
+ // Change status
2083
+ $el.removeClass('is-active').addClass('is-inactive');
2084
+
2085
+ },
2086
+ error: function(xhr, textStatus, event) {
2087
+ return false;
2088
+ }
2089
+ };
2090
+
2091
+ // Perform ajax request
2092
+ $.ajax(options);
2093
+ });
2094
+
2095
+ /**
2096
+ * Handle addon installation
2097
+ */
2098
+ $(document).on('click', '.js-install-addon', function(event) {
2099
+ event.preventDefault();
2100
+
2101
+ // Establish variables
2102
+ var $button = $(this);
2103
+ var $el = $button.parents('.addon-status');
2104
+ var $message = $el.find('.status-message');
2105
+
2106
+ // Remove errors
2107
+ $('.action-error').remove();
2108
+
2109
+ // Tell the user what's happening
2110
+ $button.text(_easingsliderAdminL10n.buttons.installing);
2111
+
2112
+ // Process the Ajax to perform the activation.
2113
+ var options = {
2114
+ url: ajaxurl,
2115
+ type: 'post',
2116
+ async: true,
2117
+ cache: false,
2118
+ dataType: 'json',
2119
+ data: {
2120
+ action: 'easingslider_install_addon',
2121
+ nonce: _easingsliderAdminL10n.nonces.install,
2122
+ plugin: $button.attr('data-plugin')
2123
+ },
2124
+ success: function(response) {
2125
+
2126
+ // If there is a WP Error instance, output it here and quit
2127
+ if ( response.error ) {
2128
+ $button.after('<div class="action-error error"><strong>'+ response.error +'</strong></div>');
2129
+ return false;
2130
+ }
2131
+
2132
+ // The Ajax request was successful, update the button.
2133
+ $button
2134
+ .attr('data-plugin', response.plugin)
2135
+ .text(_easingsliderAdminL10n.buttons.activate)
2136
+ .removeClass('js-install-addon')
2137
+ .addClass('js-activate-addon');
2138
+
2139
+ // Update message
2140
+ $message.text(_easingsliderAdminL10n.messages.inactive);
2141
+
2142
+ // Change status
2143
+ $el.removeClass('not-installed').addClass('is-inactive');
2144
+
2145
+ },
2146
+ error: function(xhr, textStatus, event) {
2147
+ return false;
2148
+ }
2149
+ };
2150
+
2151
+ // Perform ajax request
2152
+ $.ajax(options);
2153
+ });
2154
+
2155
+ });
2156
+
2157
+ })(jQuery);
assets/js/admin.min.js ADDED
@@ -0,0 +1 @@
 
1
+ window.EasingSlider=window.EasingSlider||{},window.EasingSlider.Admin=window.EasingSlider.Admin||{},_.extend(EasingSlider.Admin,{model:{},collection:{},controller:{},frame:{},view:{},toolbar:{},router:{},Router:{}}),function(a){var b=window.EasingSlider.Admin;b.model.Slide={get:function(a){return"undefined"!=typeof b.model.Slide[a.type]?new b.model.Slide[a.type](a):new b.model.Slide.base(a)}},b.model.Slide.base=Backbone.Model.extend(),b.model.Slide.image=b.model.Slide.base.extend({attachment:!1,defaults:{attachment_id:null,type:"image",alt:"",link:"none",linkUrl:"",linkTargetBlank:!1,title:"",url:null}}),b.collection.Slides=Backbone.Collection.extend({model:b.model.Slide.get,initialize:function(){this.on("add",this._resetIDs,this),this.on("remove",this._resetIDs,this),this.on("reset",this._resetIDs,this)},comparator:function(a){return a.get("id")},_resetIDs:function(){var a=new Backbone.Collection;_.each(this.models,function(b,c){b.set({id:c+1}),a.add(b)}),this.reset(a.models,{silent:!0})},reposition:function(a,b){return this.remove(a,{silent:!0}),this.add(a,{at:b,silent:!0}),this._resetIDs(),this},sync:function(){var a=this,b=[];_.each(this.models,function(a){a.has("attachment_id")&&b.push(a.get("attachment_id"))},this);var c=wp.media.query({post__in:b,posts_per_page:-1});return c.more().done(function(){_.each(c.models,function(b){var c=a.where({attachment_id:b.get("id")});_.each(c,function(a){a.attachment=b})}),a.trigger("sync:done")}),this}}),b.controller.AddSlide={get:function(a){return"undefined"!=typeof b.controller.AddSlide[a.type]?new b.controller.AddSlide[a.type](a):new b.controller.AddSlide.base(a)}},b.controller.AddSlide.base=wp.media.controller.State.extend({initialize:function(){this.props=new b.model.Slide.get({type:this.get("type")})}}),b.controller.AddSlide.image=wp.media.controller.Library.extend(),b.controller.EditSlide={get:function(a){return"undefined"!=typeof b.controller.EditSlide[a.type]?new b.controller.EditSlide[a.type](a):new b.controller.EditSlide.base(a)}},b.controller.EditSlide.base=wp.media.controller.State.extend({defaults:_.defaults({id:"edit-slide",title:_easingsliderAdminL10n.media_upload.title,content:"edit-slide",menu:!1,router:!1,toolbar:"edit-slide",editing:!1,priority:60},wp.media.controller.State.defaults)}),b.controller.EditSlide.image=b.controller.EditSlide.base.extend(),b.frame.AddSlide=wp.media.view.MediaFrame.Post.extend({initialize:function(){_.defaults(this.options,{multiple:!0}),wp.media.view.MediaFrame.Post.prototype.initialize.apply(this,arguments)},bindHandlers:function(){this.on("close",this.updateRouter,this),this.on("content:render:browse",this.removeSidebar,this),this.on("toolbar:create:insert-slide",this.createToolbar,this),this.on("toolbar:render:insert-slide",this.insertToolbar,this),wp.media.view.MediaFrame.Post.prototype.bindHandlers.apply(this,arguments)},browseContent:function(a){var c=this.state();this.$el.removeClass("hide-toolbar"),a.view=new b.view.AddSlide.image({controller:this,collection:c.get("library"),selection:c.get("selection"),model:c,sortable:c.get("sortable"),search:c.get("searchable"),filters:c.get("filterable"),date:c.get("date"),display:c.has("display")?c.get("display"):c.get("displaySettings"),dragInfo:c.get("dragInfo"),idealColumnWidth:c.get("idealColumnWidth"),suggestedWidth:c.get("suggestedWidth"),suggestedHeight:c.get("suggestedHeight"),AttachmentView:c.get("AttachmentView")})},removeSidebar:function(a){a.sidebar.remove("details"),a.$el.addClass("hide-sidebar")},createStates:function(){this.states.add([new b.controller.AddSlide.image({id:"insert",type:"image",title:_easingsliderAdminL10n.media_upload.image_from_media,priority:20,toolbar:"insert-slide",filterable:!1,library:wp.media.query({type:"image"}),multiple:!0,editable:!0,allowLocalEdits:!0,displaySettings:!1,displayUserSettings:!0})])},createIframeStates:function(){return this},insertToolbar:function(a){var b=this;a.set("insert-slide",{style:"primary",priority:80,text:_easingsliderAdminL10n.media_upload.insert_into_slider,requires:{selection:!1},click:function(){b.close().trigger("insert",b.getSelection()).reset()}})},getSelection:function(a){var c=new wp.media.model.Selection(null,{multiple:!0}),d=this.state().get("type"),a=this.state().get("selection");return _.each(a.models,function(a){var e=new b.model.Slide.get({type:d});a.get("id")?(e.attachment=a,e.set({attachment_id:a.get("id")},{silent:!0})):e.set(a,{silent:!0}),c.add(e)},this),c},updateRouter:function(){b.Router.navigate(_easingsliderAdminL10n.base_url)}}),b.frame.EditSlide={get:function(a){return"undefined"!=typeof b.frame.EditSlide[a.model.get("type")]?new(b.frame.EditSlide[a.model.get("type")])(a):new b.frame.EditSlide.base(a)}},b.frame.EditSlide.base=wp.media.view.MediaFrame.Select.extend({className:"edit-slide-frame media-frame",template:wp.template("easingslider-edit-slide-frame"),events:_.defaults({"click .left":"previousSlide","click .right":"nextSlide"},wp.media.view.MediaFrame.Select.prototype.events),initialize:function(){this.options.state="edit-slide",this.options.selection=new wp.media.model.Selection({},{multiple:!1}),wp.media.view.MediaFrame.Select.prototype.initialize.apply(this,arguments)},bindHandlers:function(){this.on("close",this.updateRouter,this),this.on("content:create:edit-slide",this.createView,this),this.on("toolbar:render:edit-slide",this.createToolbar,this),wp.media.view.MediaFrame.Select.prototype.bindHandlers.apply(this,arguments)},createView:function(a){a.view=new b.view.EditSlide.get({type:this.model.get("type"),model:this.model,controller:this})},createToolbar:function(){this.toolbar.set(new wp.media.view.Toolbar({controller:this,items:{select:{style:"primary",text:_easingsliderAdminL10n.media_upload.update,priority:80,click:function(){var a=this.controller,b=a.state();a.close(),b.trigger("update",a.model.toJSON()),a.setState(a.options.state),a.reset()}}}}))},createStates:function(){this.states.add([new b.controller.EditSlide.get({type:this.model.get("type")})]),wp.media.view.MediaFrame.Select.prototype.createStates.apply(this,arguments)},render:function(){return wp.media.view.MediaFrame.Select.prototype.render.apply(this,arguments),this.toggleNav(),this},rerender:function(){return this.content.render(),this.toggleNav(),this},toggleNav:function(){return this.$(".left").removeProp("disabled").removeClass("disabled"),this.$(".right").removeProp("disabled").removeClass("disabled"),this.hasPrevious()||this.$(".left").prop("disabled","disabled").addClass("disabled"),this.hasNext()||this.$(".right").prop("disabled","disabled").addClass("disabled"),this},previousSlide:function(){return this.hasPrevious()?(this.model=this.collection.at(this.collection.indexOf(this.model)-1),this.rerender(),void this.$(".left").focus()):void this.$(".left").blur()},nextSlide:function(){return this.hasNext()?(this.model=this.collection.at(this.collection.indexOf(this.model)+1),this.rerender(),void this.$(".right").focus()):void this.$(".right").blur()},hasNext:function(){return this.collection.indexOf(this.model)+1<this.collection.length},hasPrevious:function(){return this.collection.indexOf(this.model)-1>-1},updateRouter:function(){b.Router.navigate(_easingsliderAdminL10n.base_url)}}),b.frame.EditSlide.image=b.frame.EditSlide.base.extend({initialize:function(){this.image=new wp.media.model.PostImage(this.model.attributes),b.frame.EditSlide.base.prototype.initialize.apply(this,arguments)},bindHandlers:function(){this.on("content:create:browse",this.modifyBrowseFilters,this),this.on("content:render:browse",this.removeBrowseSidebar,this),this.on("content:render:edit-slide",this.showNav,this),this.on("content:render:edit-image",this.renderEditImageContent,this),this.on("toolbar:render:replace",this.hideNav,this),this.on("toolbar:render:replace",this.renderReplaceImageToolbar,this),this.state("replace-image").on("replace",this.replaceImage,this),b.frame.EditSlide.base.prototype.bindHandlers.apply(this,arguments)},createStates:function(){b.frame.EditSlide.base.prototype.createStates.apply(this,arguments),this.states.add([new wp.media.controller.ReplaceImage({id:"replace-image",library:wp.media.query({type:"image"}),image:this.image,multiple:!1,title:_easingsliderAdminL10n.media_upload.replace_image,toolbar:"replace",priority:80,displaySettings:!0}),new wp.media.controller.EditImage({image:this.image,selection:this.options.selection})])},modifyBrowseFilters:function(a){this.state().set("filterable",!0)},removeBrowseSidebar:function(a){a.sidebar.remove("details"),a.$el.addClass("hide-sidebar")},showNav:function(){this.$(".left, .right").show(),a(".media-modal-close").removeClass("no-border")},hideNav:function(){this.$(".left, .right").hide(),a(".media-modal-close").addClass("no-border")},renderEditImageContent:function(){var a,b=this.state(),c=b.get("image");c&&(a=new wp.media.view.EditImage({model:c,controller:this}).render(),this.content.set(a),a.loadEditor())},renderReplaceImageToolbar:function(){var a=this,b=a.lastState(),c=b&&b.id;this.toolbar.set(new wp.media.view.Toolbar({controller:this,items:{back:{text:_easingsliderAdminL10n.media_upload.back,priority:20,click:function(){c?a.setState(c):a.close()}},replace:{style:"primary",text:_easingsliderAdminL10n.media_upload.replace,priority:80,click:function(){var a=this.controller,b=a.state(),c=b.get("selection"),d=c.single();a.close(),a.image.changeAttachment(d,b.display(d)),b.trigger("replace",a.image.toJSON()),a.setState(a.options.state),a.reset()}}}}))},replaceImage:function(){this.model.set({attachment_id:this.image.attachment.id}),this.model.attachment.set(this.image.attachment.attributes)}}),b.view.Editor=Backbone.View.extend({el:".wrap",events:{"click #add-slides":"_addSlide","click #select-all":"_selectAll","click #delete-slides":"_clickBulkDelete","click #save":"_clickSave","click .toolbar .edit":"_clickEdit","click .toolbar .remove":"_clickDelete","click .show-advanced-options":"_clickAdvancedOptions","click .thumbnail":"_clickThumb","click .select-mode-toggle-button":"_toggleMode","click .sidebar-name":"_toggleWidget"},initialize:function(){this.subviews={AddSlide:new b.frame.AddSlide,Slides:new b.view.Slides({collection:this.collection})},this.collection.on("sync:done",this.render,this),this.collection.on("sync:done",this._enableSave,this),this.collection.on("sync:done",this._handleNoSlides,this),this.collection.on("add",this._handleNoSlides,this),this.collection.on("remove",this._handleNoSlides,this),this.subviews.AddSlide.on("insert",this._handleInsert,this),a(window).on("resize",this._setColumns.bind(this)),this._selectMode=!1,this._setColumns(),this._showSpinner()},_showSpinner:function(){this.$("#slides-browser").append('<div class="spinner"></div>')},_hideSpinner:function(){this.$("#slides-browser .spinner").remove()},_enableSave:function(){this.$("#save").prop("disabled",!1)},_clickSave:function(){this.$("#publishing-action .spinner").css({display:"block"})},_setColumns:function(){var a=this.$(".media-frame-content"),b=a.attr("data-columns"),c=a.width();if(c){var d=Math.min(Math.round(c/145),12)||1;b&&b===d||a.attr("data-columns",d)}},_handleNoSlides:function(){0==this.collection.length?this.$("form").prepend('<input type="hidden" id="slides" name="slides" value="[]" />'):this.$('input[name="slides"]').remove()},_handleInsert:function(a){this.collection.add(a.models)},_clickThumb:function(a){a.preventDefault(),this._selectMode?this._toggleSelect(a):this._editSlide(a)},_clickEdit:function(a){a.preventDefault(),this._editSlide(a)},_clickDelete:function(b){if(b.preventDefault(),confirm(_easingsliderAdminL10n.warn)){var c=a(b.currentTarget).parents(".attachment").attr("data-id");this.collection.remove(c)}},_clickBulkDelete:function(a){a.preventDefault(),confirm(_easingsliderAdminL10n.warn)&&(this._deleteSlides(a),this._toggleMode(a))},_clickAdvancedOptions:function(b){b.preventDefault();var c=a(b.currentTarget).parent().find(".advanced-options");c.toggleClass("hide")},_toggleMode:function(a){a.preventDefault(),this._selectMode?this._selectMode=!1:this._selectMode=!0,this.$(".attachment").removeClass("selected details"),this.$(".media-frame").toggleClass("mode-select"),this.$(".media-toolbar div *").toggleClass("hide")},_toggleSelect:function(b){b.preventDefault(),a(b.currentTarget).parents(".attachment").toggleClass("selected details")},_toggleWidget:function(b){b.preventDefault();var c=a(b.currentTarget).parent(),d=c.find(".sidebar-content");c.hasClass("fixed")||(this.$(".widgets-holder-wrap").each(function(){var b=a(this);b.hasClass("fixed")||b.find(".sidebar-content").slideUp(200,function(){b.addClass("closed")})}),c.hasClass("closed")&&d.slideDown(200,function(){c.removeClass("closed")}))},_selectAll:function(a){a.preventDefault(),this.$(".attachment").addClass("selected details")},_deleteSlides:function(b){b.preventDefault();var c=this.collection,d=[];this.$(".attachment").each(function(b){a(this).hasClass("selected")&&d.push(c.at(b))}),this.collection.remove(d)},_addSlide:function(a){a.preventDefault(),this.addSlide(),b.Router.navigate(_easingsliderAdminL10n.base_url+"&add=true")},addSlide:function(){return this.subviews.AddSlide.open(),this},_editSlide:function(c){c.preventDefault();var d=a(c.currentTarget).parents(".attachment").attr("data-id");this.editSlide(d),b.Router.navigate(_easingsliderAdminL10n.base_url+"&slide="+d)},editSlide:function(a){return this.subviews.EditSlide=new b.frame.EditSlide.get({collection:this.collection,model:this.collection.get(a)}),this.subviews.EditSlide.open(),this},newAddSlideFrame:function(a){var c=this.subviews.AddSlide;c.states.add([new b.controller.AddSlide.get(a)]),c.on("content:render:"+a.content,function(){var c=new b.view.AddSlide.get({type:a.content,model:this.state().props,controller:this});this.content.set(c)},c),c.on("toolbar:render:"+a.toolbar,function(){var c=new b.toolbar.AddSlide.get({type:a.toolbar,controller:this});this.toolbar.set(c)},c)},render:function(){this._hideSpinner();var a=this.subviews.Slides.render().el;return this.$("#slides-browser").append(a),this}}),b.view.Slides=Backbone.View.extend({tagName:"ul",attributes:{"class":"attachments ui-sortable",tabindex:"-1"},initialize:function(){this.subviews=[],this.collection.on("add",this.add,this),this.collection.on("remove",this.render,this),this.collection.on("reset",this.render,this),this.$el.sortable({items:".attachment",containment:"parent",tolerance:"pointer",stop:this._sort.bind(this)})},_sort:function(a,b){var c=this.collection.get(b.item.context.dataset.id);this.collection.reposition(c,b.item.index())},add:function(a){var c=new b.view.Slide({model:a});return this.subviews.push(c),this.$el.append(c.render().$el),this},render:function(){return this.subviews=[],this.$el.empty(),_.each(this.collection.models,function(a){this.add(a)},this),this}}),b.view.Slide=Backbone.View.extend({tagName:"li",attributes:function(){return{role:"checkbox","class":"attachment save-ready",tabindex:"0","data-id":this.model.id}},template:wp.media.template("easingslider-slide"),initialize:function(){this.model.on("change",this._setData,this),this.model.on("change:id",this._updateID,this),this.model.on("change:url",this.render,this),this.model.on("change:poster",this.render,this),this.model.on("change:attachment_id",this.render,this),this.model.attachment&&this.model.attachment.on("change",this.render,this)},_setData:function(){this.$('input[name="slides[]"]').val(JSON.stringify(this.model.attributes))},_updateID:function(a,b){this.$el.attr("data-id",b),this.attributes["data-id"]=b},render:function(){var a={model:this.model.toJSON()};return this.model.attachment&&(a.attachment=this.model.attachment.toJSON()),this.$el.html(this.template(a)),this}}),b.view.AddSlide={get:function(a){return"undefined"!=typeof b.view.AddSlide[a.type]?new b.view.AddSlide[a.type](a):new b.view.AddSlide.base(a)}},b.view.AddSlide.base=wp.media.View.extend(),b.view.AddSlide.image=wp.media.view.AttachmentsBrowser.extend(),b.view.EditSlide={get:function(a){return"undefined"!=typeof b.view.EditSlide[a.type]?new b.view.EditSlide[a.type](a):new b.view.EditSlide.base(a)}},b.view.EditSlide.base=wp.media.view.Settings.extend({className:"edit-attachment-frame attachment-details mode-select",template:wp.media.template("easingslider-edit-slide"),initialize:function(){wp.media.view.Settings.prototype.initialize.apply(this,arguments),this.model.on("change:link",this.toggleLinkSettings,this),this.model.on("change:link",this.updateLinkTo,this)},prepare:function(){var a=!1;return this.model.attachment&&(a=this.model.attachment.toJSON()),_.defaults({model:this.model.toJSON(),attachment:a},this.options)},toggleLinkSettings:function(){"none"===this.model.get("link")?this.$(".link-options").addClass("hide"):this.$(".link-options").removeClass("hide")},updateLinkTo:function(){var a=this.model.get("link"),b=this.$(".link-to-custom");if(this.model.attachment){if("none"===a||"embed"===a||!this.model.attachment&&"custom"!==a)return void b.addClass("hidden");this.model.attachment&&("post"===a?b.val(this.model.attachment.get("link")):"file"===a?b.val(this.model.attachment.get("url")):this.model.get("linkUrl")||b.val("http://"),b.prop("readonly","custom"!==a)),b.removeClass("hidden"),!wp.media.isTouchDevice&&b.is(":visible")&&b.focus()[0].select()}},render:function(){return wp.media.view.Settings.prototype.render.apply(this,arguments),this.toggleLinkSettings(),this.updateLinkTo(),this}}),b.view.EditSlide.image=b.view.EditSlide.base.extend({events:_.defaults({"click .edit-attachment":"editAttachment","click .replace-attachment":"replaceAttachment"},b.view.EditSlide.base.prototype.events),initialize:function(){b.view.EditSlide.base.prototype.initialize.apply(this,arguments),this.model.on("change:url",this.updateImage,this)},editAttachment:function(a){var b=this.controller.states.get("edit-image");window.imageEdit&&b&&(a.preventDefault(),b.set("image",this.model.attachment),this.controller.setState("edit-image"))},replaceAttachment:function(a){a.preventDefault(),this.controller.setState("replace-image")},updateImage:function(){this.$(".details-image").attr("src",this.model.get("url"))}}),b.toolbar.AddSlide={get:function(a){return"undefined"!=typeof b.toolbar.AddSlide[a.type]?new b.toolbar.AddSlide[a.type](a):new b.toolbar.AddSlide.base(a)}},b.toolbar.AddSlide.base=wp.media.view.Toolbar.extend(),b.router=Backbone.Router.extend({routes:{"admin.php?page=:page&edit=:id&slide=:slide":"editSlide","admin.php?page=:page&edit=:id&add=true":"addSlide","admin.php?page=:page&edit=:id":"editor","admin.php?page=easingslider-add-new":"editor"},initialize:function(){var a="undefined"==typeof window.slides?"[]":window.slides;this.view=new b.view.Editor({collection:new b.collection.Slides(JSON.parse(a))})},editSlide:function(a,b,c){return this.editor(),this.view.collection.on("sync:done",function(){this.view.editSlide(c)},this),this},addSlide:function(a,b){return this.editor(),this.view.collection.on("sync:done",function(){this.view.addSlide()},this),this},editor:function(a){return this.view.collection.sync(),this}}),a(document).ready(function(){b.Router=new b.router,Backbone.history.start({root:window._easingsliderAdminL10n.admin_url,pushState:!0}),a(".delete").each(function(){a(this).on("click",function(){return confirm(_easingsliderAdminL10n.warn)?void 0:!1})}),a('select[name="type"]').on("change",function(){a("*[data-type]").addClass("hidden"),a('*[data-type="'+this.value+'"]').removeClass("hidden"),"media"!=this.value?a(".media-toolbar-primary").addClass("hidden"):a(".media-toolbar-primary").removeClass("hidden")}),a(document).on("click",".js-activate-addon",function(b){b.preventDefault();var c=a(this),d=c.parents(".addon-status"),e=d.find(".status-message");a(".action-error").remove(),c.text(_easingsliderAdminL10n.buttons.activating);var f={url:ajaxurl,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"easingslider_activate_addon",nonce:_easingsliderAdminL10n.nonces.activate,plugin:c.attr("data-plugin")},success:function(a){return a&&!0!==a?(c.after('<div class="action-error error"><strong>'+a.error+"</strong></div>"),!1):(c.text(_easingsliderAdminL10n.buttons.deactivate).removeClass("js-activate-addon").addClass("js-deactivate-addon"),e.text(_easingsliderAdminL10n.messages.active),void d.removeClass("is-inactive").addClass("is-active"))},error:function(a,b,c){return!1}};a.ajax(f)}),a(document).on("click",".js-deactivate-addon",function(b){b.preventDefault();var c=a(this),d=c.parents(".addon-status"),e=d.find(".status-message");a(".action-error").remove(),c.text(_easingsliderAdminL10n.buttons.deactivating);var f={url:ajaxurl,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"easingslider_deactivate_addon",nonce:_easingsliderAdminL10n.nonces.deactivate,plugin:c.attr("data-plugin")},success:function(a){return a&&!0!==a?(c.after('<div class="action-error error"><strong>'+a.error+"</strong></div>"),!1):(c.text(_easingsliderAdminL10n.buttons.activate).removeClass("js-deactivate-addon").addClass("js-activate-addon"),e.text(_easingsliderAdminL10n.messages.inactive),void d.removeClass("is-active").addClass("is-inactive"))},error:function(a,b,c){return!1}};a.ajax(f)}),a(document).on("click",".js-install-addon",function(b){b.preventDefault();var c=a(this),d=c.parents(".addon-status"),e=d.find(".status-message");a(".action-error").remove(),c.text(_easingsliderAdminL10n.buttons.installing);var f={url:ajaxurl,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"easingslider_install_addon",nonce:_easingsliderAdminL10n.nonces.install,plugin:c.attr("data-plugin")},success:function(a){return a.error?(c.after('<div class="action-error error"><strong>'+a.error+"</strong></div>"),!1):(c.attr("data-plugin",a.plugin).text(_easingsliderAdminL10n.buttons.activate).removeClass("js-install-addon").addClass("js-activate-addon"),e.text(_easingsliderAdminL10n.messages.inactive),void d.removeClass("not-installed").addClass("is-inactive"))},error:function(a,b,c){return!1}};a.ajax(f)})})}(jQuery);
assets/js/public.js ADDED
@@ -0,0 +1,1635 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery OwlCarousel v1.3.2
3
+ *
4
+ * Copyright (c) 2013 Bartosz Wojciechowski
5
+ * http://www.easingslidergraphic.com/easingslidercarousel/
6
+ *
7
+ * Licensed under MIT
8
+ *
9
+ */
10
+
11
+ /*JS Lint helpers: */
12
+ /*global dragMove: false, dragEnd: false, $, jQuery, alert, window, document */
13
+ /*jslint nomen: true, continue:true */
14
+
15
+ if (typeof Object.create !== "function") {
16
+ Object.create = function (obj) {
17
+ function F() {}
18
+ F.prototype = obj;
19
+ return new F();
20
+ };
21
+ }
22
+ (function ($, window, document) {
23
+
24
+ var Carousel = {
25
+ init : function (options, el) {
26
+ var base = this;
27
+
28
+ base.$elem = $(el);
29
+ base.options = $.extend({}, $.fn.easingSlider.options, base.$elem.data(), options);
30
+
31
+ base.userOptions = options;
32
+ base.loadContent();
33
+ },
34
+
35
+ loadContent : function () {
36
+ var base = this, url;
37
+
38
+ function getData(data) {
39
+ var i, content = "";
40
+ if (typeof base.options.jsonSuccess === "function") {
41
+ base.options.jsonSuccess.apply(this, [data]);
42
+ } else {
43
+ for (i in data.easingslider) {
44
+ if (data.easingslider.hasOwnProperty(i)) {
45
+ content += data.easingslider[i].item;
46
+ }
47
+ }
48
+ base.$elem.html(content);
49
+ }
50
+ base.logIn();
51
+ }
52
+
53
+ if (typeof base.options.beforeInit === "function") {
54
+ base.options.beforeInit.apply(this, [base.$elem]);
55
+ }
56
+
57
+ if (typeof base.options.jsonPath === "string") {
58
+ url = base.options.jsonPath;
59
+ $.getJSON(url, getData);
60
+ } else {
61
+ base.logIn();
62
+ }
63
+ },
64
+
65
+ logIn : function () {
66
+ var base = this;
67
+
68
+ base.$elem.data("easingslider-originalStyles", base.$elem.attr("style"))
69
+ .data("easingslider-originalClasses", base.$elem.attr("class"));
70
+
71
+ base.$elem.css({opacity: 0});
72
+ base.orignalItems = base.options.items;
73
+ base.checkBrowser();
74
+ base.wrapperWidth = 0;
75
+ base.checkVisible = null;
76
+ base.setVars();
77
+ },
78
+
79
+ setVars : function () {
80
+ var base = this;
81
+ if (base.$elem.children().length === 0) {return false; }
82
+ base.baseClass();
83
+ base.eventTypes();
84
+ base.$userItems = base.$elem.children();
85
+ base.itemsAmount = base.$userItems.length;
86
+ base.wrapItems();
87
+ base.$easingsliderItems = base.$elem.find(".easingslider-item");
88
+ base.$easingsliderWrapper = base.$elem.find(".easingslider-wrapper");
89
+ base.playDirection = "next";
90
+ base.prevItem = 0;
91
+ base.prevArr = [0];
92
+ base.currentItem = 0;
93
+ base.customEvents();
94
+ base.onStartup();
95
+ },
96
+
97
+ onStartup : function () {
98
+ var base = this;
99
+ base.updateItems();
100
+ base.calculateAll();
101
+ base.buildControls();
102
+ base.updateControls();
103
+ base.response();
104
+ base.moveEvents();
105
+ base.stopOnHover();
106
+ base.easingsliderStatus();
107
+
108
+ if (base.options.transitionStyle !== false) {
109
+ base.transitionTypes(base.options.transitionStyle);
110
+ }
111
+ if (base.options.autoPlay === true) {
112
+ base.options.autoPlay = 5000;
113
+ }
114
+ base.play();
115
+
116
+ base.$elem.find(".easingslider-wrapper").css("display", "block");
117
+
118
+ if (!base.$elem.is(":visible")) {
119
+ base.watchVisibility();
120
+ } else {
121
+ base.$elem.css("opacity", 1);
122
+ }
123
+ base.onstartup = false;
124
+ base.eachMoveUpdate();
125
+ if (typeof base.options.afterInit === "function") {
126
+ base.options.afterInit.apply(this, [base.$elem]);
127
+ }
128
+ },
129
+
130
+ eachMoveUpdate : function () {
131
+ var base = this;
132
+
133
+ if (base.options.lazyLoad === true) {
134
+ base.lazyLoad();
135
+ }
136
+ if (base.options.autoHeight === true) {
137
+ base.autoHeight();
138
+ }
139
+ base.onVisibleItems();
140
+
141
+ if (typeof base.options.afterAction === "function") {
142
+ base.options.afterAction.apply(this, [base.$elem]);
143
+ }
144
+ },
145
+
146
+ updateVars : function () {
147
+ var base = this;
148
+ if (typeof base.options.beforeUpdate === "function") {
149
+ base.options.beforeUpdate.apply(this, [base.$elem]);
150
+ }
151
+ base.watchVisibility();
152
+ base.updateItems();
153
+ base.calculateAll();
154
+ base.updatePosition();
155
+ base.updateControls();
156
+ base.eachMoveUpdate();
157
+ if (typeof base.options.afterUpdate === "function") {
158
+ base.options.afterUpdate.apply(this, [base.$elem]);
159
+ }
160
+ },
161
+
162
+ reload : function () {
163
+ var base = this;
164
+ window.setTimeout(function () {
165
+ base.updateVars();
166
+ }, 0);
167
+ },
168
+
169
+ watchVisibility : function () {
170
+ var base = this;
171
+
172
+ if (base.$elem.is(":visible") === false) {
173
+ base.$elem.css({opacity: 0});
174
+ window.clearInterval(base.autoPlayInterval);
175
+ window.clearInterval(base.checkVisible);
176
+ } else {
177
+ return false;
178
+ }
179
+ base.checkVisible = window.setInterval(function () {
180
+ if (base.$elem.is(":visible")) {
181
+ base.reload();
182
+ base.$elem.animate({opacity: 1}, 200);
183
+ window.clearInterval(base.checkVisible);
184
+ }
185
+ }, 500);
186
+ },
187
+
188
+ wrapItems : function () {
189
+ var base = this;
190
+ base.$userItems.wrapAll("<div class=\"easingslider-wrapper\">").wrap("<div class=\"easingslider-item\"></div>");
191
+ base.$elem.find(".easingslider-wrapper").wrap("<div class=\"easingslider-wrapper-outer\">");
192
+ base.wrapperOuter = base.$elem.find(".easingslider-wrapper-outer");
193
+ base.$elem.css("display", "block");
194
+ },
195
+
196
+ baseClass : function () {
197
+ var base = this,
198
+ hasBaseClass = base.$elem.hasClass(base.options.baseClass),
199
+ hasThemeClass = base.$elem.hasClass(base.options.theme);
200
+
201
+ if (!hasBaseClass) {
202
+ base.$elem.addClass(base.options.baseClass);
203
+ }
204
+
205
+ if (!hasThemeClass) {
206
+ base.$elem.addClass(base.options.theme);
207
+ }
208
+ },
209
+
210
+ updateItems : function () {
211
+ var base = this, width, i;
212
+
213
+ if (base.options.responsive === false) {
214
+ return false;
215
+ }
216
+ if (base.options.singleItem === true) {
217
+ base.options.items = base.orignalItems = 1;
218
+ base.options.itemsCustom = false;
219
+ base.options.itemsDesktop = false;
220
+ base.options.itemsDesktopSmall = false;
221
+ base.options.itemsTablet = false;
222
+ base.options.itemsTabletSmall = false;
223
+ base.options.itemsMobile = false;
224
+ return false;
225
+ }
226
+
227
+ width = $(base.options.responsiveBaseWidth).width();
228
+
229
+ if (width > (base.options.itemsDesktop[0] || base.orignalItems)) {
230
+ base.options.items = base.orignalItems;
231
+ }
232
+ if (base.options.itemsCustom !== false) {
233
+ //Reorder array by screen size
234
+ base.options.itemsCustom.sort(function (a, b) {return a[0] - b[0]; });
235
+
236
+ for (i = 0; i < base.options.itemsCustom.length; i += 1) {
237
+ if (base.options.itemsCustom[i][0] <= width) {
238
+ base.options.items = base.options.itemsCustom[i][1];
239
+ }
240
+ }
241
+
242
+ } else {
243
+
244
+ if (width <= base.options.itemsDesktop[0] && base.options.itemsDesktop !== false) {
245
+ base.options.items = base.options.itemsDesktop[1];
246
+ }
247
+
248
+ if (width <= base.options.itemsDesktopSmall[0] && base.options.itemsDesktopSmall !== false) {
249
+ base.options.items = base.options.itemsDesktopSmall[1];
250
+ }
251
+
252
+ if (width <= base.options.itemsTablet[0] && base.options.itemsTablet !== false) {
253
+ base.options.items = base.options.itemsTablet[1];
254
+ }
255
+
256
+ if (width <= base.options.itemsTabletSmall[0] && base.options.itemsTabletSmall !== false) {
257
+ base.options.items = base.options.itemsTabletSmall[1];
258
+ }
259
+
260
+ if (width <= base.options.itemsMobile[0] && base.options.itemsMobile !== false) {
261
+ base.options.items = base.options.itemsMobile[1];
262
+ }
263
+ }
264
+
265
+ //if number of items is less than declared
266
+ if (base.options.items > base.itemsAmount && base.options.itemsScaleUp === true) {
267
+ base.options.items = base.itemsAmount;
268
+ }
269
+ },
270
+
271
+ response : function () {
272
+ var base = this,
273
+ smallDelay,
274
+ lastWindowWidth;
275
+
276
+ if (base.options.responsive !== true) {
277
+ return false;
278
+ }
279
+ lastWindowWidth = $(window).width();
280
+
281
+ base.resizer = function () {
282
+ if ($(window).width() !== lastWindowWidth) {
283
+ if (base.options.autoPlay !== false) {
284
+ window.clearInterval(base.autoPlayInterval);
285
+ }
286
+ window.clearTimeout(smallDelay);
287
+ smallDelay = window.setTimeout(function () {
288
+ lastWindowWidth = $(window).width();
289
+ base.updateVars();
290
+ }, base.options.responsiveRefreshRate);
291
+ }
292
+ };
293
+ $(window).resize(base.resizer);
294
+ },
295
+
296
+ updatePosition : function () {
297
+ var base = this;
298
+ base.jumpTo(base.currentItem);
299
+ if (base.options.autoPlay !== false) {
300
+ base.checkAp();
301
+ }
302
+ },
303
+
304
+ appendItemsSizes : function () {
305
+ var base = this,
306
+ roundPages = 0,
307
+ lastItem = base.itemsAmount - base.options.items;
308
+
309
+ base.$easingsliderItems.each(function (index) {
310
+ var $this = $(this);
311
+ $this
312
+ .css({"width": base.itemWidth})
313
+ .data("easingslider-item", Number(index));
314
+
315
+ if (index % base.options.items === 0 || index === lastItem) {
316
+ if (!(index > lastItem)) {
317
+ roundPages += 1;
318
+ }
319
+ }
320
+ $this.data("easingslider-roundPages", roundPages);
321
+ });
322
+ },
323
+
324
+ appendWrapperSizes : function () {
325
+ var base = this,
326
+ width = base.$easingsliderItems.length * base.itemWidth;
327
+
328
+ base.$easingsliderWrapper.css({
329
+ "width": width * 2,
330
+ "left": 0
331
+ });
332
+ base.appendItemsSizes();
333
+ },
334
+
335
+ calculateAll : function () {
336
+ var base = this;
337
+ base.calculateWidth();
338
+ base.appendWrapperSizes();
339
+ base.loops();
340
+ base.max();
341
+ },
342
+
343
+ calculateWidth : function () {
344
+ var base = this;
345
+ base.itemWidth = Math.round(base.$elem.width() / base.options.items);
346
+ },
347
+
348
+ max : function () {
349
+ var base = this,
350
+ maximum = ((base.itemsAmount * base.itemWidth) - base.options.items * base.itemWidth) * -1;
351
+ if (base.options.items > base.itemsAmount) {
352
+ base.maximumItem = 0;
353
+ maximum = 0;
354
+ base.maximumPixels = 0;
355
+ } else {
356
+ base.maximumItem = base.itemsAmount - base.options.items;
357
+ base.maximumPixels = maximum;
358
+ }
359
+ return maximum;
360
+ },
361
+
362
+ min : function () {
363
+ return 0;
364
+ },
365
+
366
+ loops : function () {
367
+ var base = this,
368
+ prev = 0,
369
+ elWidth = 0,
370
+ i,
371
+ item,
372
+ roundPageNum;
373
+
374
+ base.positionsInArray = [0];
375
+ base.pagesInArray = [];
376
+
377
+ for (i = 0; i < base.itemsAmount; i += 1) {
378
+ elWidth += base.itemWidth;
379
+ base.positionsInArray.push(-elWidth);
380
+
381
+ if (base.options.scrollPerPage === true) {
382
+ item = $(base.$easingsliderItems[i]);
383
+ roundPageNum = item.data("easingslider-roundPages");
384
+ if (roundPageNum !== prev) {
385
+ base.pagesInArray[prev] = base.positionsInArray[i];
386
+ prev = roundPageNum;
387
+ }
388
+ }
389
+ }
390
+ },
391
+
392
+ buildControls : function () {
393
+ var base = this;
394
+ if (base.options.navigation === true || base.options.pagination === true) {
395
+ base.easingsliderControls = $("<div class=\"easingslider-controls\"/>").toggleClass("clickable", !base.browser.isTouch).appendTo(base.$elem);
396
+ }
397
+ if (base.options.pagination === true) {
398
+ base.buildPagination();
399
+ }
400
+ if (base.options.navigation === true) {
401
+ base.buildButtons();
402
+ }
403
+ },
404
+
405
+ buildButtons : function () {
406
+ var base = this,
407
+ buttonsWrapper = $("<div class=\"easingslider-buttons\"/>");
408
+ base.easingsliderControls.append(buttonsWrapper);
409
+
410
+ base.buttonPrev = $("<div/>", {
411
+ "class" : "easingslider-prev",
412
+ "html" : base.options.navigationText[0] || ""
413
+ });
414
+
415
+ base.buttonNext = $("<div/>", {
416
+ "class" : "easingslider-next",
417
+ "html" : base.options.navigationText[1] || ""
418
+ });
419
+
420
+ buttonsWrapper
421
+ .append(base.buttonPrev)
422
+ .append(base.buttonNext);
423
+
424
+ buttonsWrapper.on("touchstart.easingsliderControls mousedown.easingsliderControls", "div[class^=\"easingslider\"]", function (event) {
425
+ event.preventDefault();
426
+ });
427
+
428
+ buttonsWrapper.on("touchend.easingsliderControls mouseup.easingsliderControls", "div[class^=\"easingslider\"]", function (event) {
429
+ event.preventDefault();
430
+ if ($(this).hasClass("easingslider-next")) {
431
+ base.next();
432
+ } else {
433
+ base.prev();
434
+ }
435
+ });
436
+ },
437
+
438
+ buildPagination : function () {
439
+ var base = this;
440
+
441
+ base.paginationWrapper = $("<div class=\"easingslider-pagination\"/>");
442
+ base.easingsliderControls.append(base.paginationWrapper);
443
+
444
+ base.paginationWrapper.on("touchend.easingsliderControls mouseup.easingsliderControls", ".easingslider-page", function (event) {
445
+ event.preventDefault();
446
+ if (Number($(this).data("easingslider-page")) !== base.currentItem) {
447
+ base.goTo(Number($(this).data("easingslider-page")), true);
448
+ }
449
+ });
450
+ },
451
+
452
+ updatePagination : function () {
453
+ var base = this,
454
+ counter,
455
+ lastPage,
456
+ lastItem,
457
+ i,
458
+ paginationButton,
459
+ paginationButtonInner;
460
+
461
+ if (base.options.pagination === false) {
462
+ return false;
463
+ }
464
+
465
+ base.paginationWrapper.html("");
466
+
467
+ counter = 0;
468
+ lastPage = base.itemsAmount - base.itemsAmount % base.options.items;
469
+
470
+ for (i = 0; i < base.itemsAmount; i += 1) {
471
+ if (i % base.options.items === 0) {
472
+ counter += 1;
473
+ if (lastPage === i) {
474
+ lastItem = base.itemsAmount - base.options.items;
475
+ }
476
+ paginationButton = $("<div/>", {
477
+ "class" : "easingslider-page"
478
+ });
479
+ paginationButtonInner = $("<span></span>", {
480
+ "text": base.options.paginationNumbers === true ? counter : "",
481
+ "class": base.options.paginationNumbers === true ? "easingslider-numbers" : ""
482
+ });
483
+ paginationButton.append(paginationButtonInner);
484
+
485
+ paginationButton.data("easingslider-page", lastPage === i ? lastItem : i);
486
+ paginationButton.data("easingslider-roundPages", counter);
487
+
488
+ base.paginationWrapper.append(paginationButton);
489
+ }
490
+ }
491
+ base.checkPagination();
492
+ },
493
+ checkPagination : function () {
494
+ var base = this;
495
+ if (base.options.pagination === false) {
496
+ return false;
497
+ }
498
+ base.paginationWrapper.find(".easingslider-page").each(function () {
499
+ if ($(this).data("easingslider-roundPages") === $(base.$easingsliderItems[base.currentItem]).data("easingslider-roundPages")) {
500
+ base.paginationWrapper
501
+ .find(".easingslider-page")
502
+ .removeClass("active");
503
+ $(this).addClass("active");
504
+ }
505
+ });
506
+ },
507
+
508
+ checkNavigation : function () {
509
+ var base = this;
510
+
511
+ if (base.options.navigation === false) {
512
+ return false;
513
+ }
514
+ if (base.options.rewindNav === false) {
515
+ if (base.currentItem === 0 && base.maximumItem === 0) {
516
+ base.buttonPrev.addClass("disabled");
517
+ base.buttonNext.addClass("disabled");
518
+ } else if (base.currentItem === 0 && base.maximumItem !== 0) {
519
+ base.buttonPrev.addClass("disabled");
520
+ base.buttonNext.removeClass("disabled");
521
+ } else if (base.currentItem === base.maximumItem) {
522
+ base.buttonPrev.removeClass("disabled");
523
+ base.buttonNext.addClass("disabled");
524
+ } else if (base.currentItem !== 0 && base.currentItem !== base.maximumItem) {
525
+ base.buttonPrev.removeClass("disabled");
526
+ base.buttonNext.removeClass("disabled");
527
+ }
528
+ }
529
+ },
530
+
531
+ updateControls : function () {
532
+ var base = this;
533
+ base.updatePagination();
534
+ base.checkNavigation();
535
+ if (base.easingsliderControls) {
536
+ if (base.options.items >= base.itemsAmount) {
537
+ base.easingsliderControls.hide();
538
+ } else {
539
+ base.easingsliderControls.show();
540
+ }
541
+ }
542
+ },
543
+
544
+ destroyControls : function () {
545
+ var base = this;
546
+ if (base.easingsliderControls) {
547
+ base.easingsliderControls.remove();
548
+ }
549
+ },
550
+
551
+ next : function (speed) {
552
+ var base = this;
553
+
554
+ if (base.isTransition) {
555
+ return false;
556
+ }
557
+
558
+ base.currentItem += base.options.scrollPerPage === true ? base.options.items : 1;
559
+ if (base.currentItem > base.maximumItem + (base.options.scrollPerPage === true ? (base.options.items - 1) : 0)) {
560
+ if (base.options.rewindNav === true) {
561
+ base.currentItem = 0;
562
+ speed = "rewind";
563
+ } else {
564
+ base.currentItem = base.maximumItem;
565
+ return false;
566
+ }
567
+ }
568
+ base.goTo(base.currentItem, speed);
569
+ },
570
+
571
+ prev : function (speed) {
572
+ var base = this;
573
+
574
+ if (base.isTransition) {
575
+ return false;
576
+ }
577
+
578
+ if (base.options.scrollPerPage === true && base.currentItem > 0 && base.currentItem < base.options.items) {
579
+ base.currentItem = 0;
580
+ } else {
581
+ base.currentItem -= base.options.scrollPerPage === true ? base.options.items : 1;
582
+ }
583
+ if (base.currentItem < 0) {
584
+ if (base.options.rewindNav === true) {
585
+ base.currentItem = base.maximumItem;
586
+ speed = "rewind";
587
+ } else {
588
+ base.currentItem = 0;
589
+ return false;
590
+ }
591
+ }
592
+ base.goTo(base.currentItem, speed);
593
+ },
594
+
595
+ goTo : function (position, speed, drag) {
596
+ var base = this,
597
+ goToPixel;
598
+
599
+ if (base.isTransition) {
600
+ return false;
601
+ }
602
+ if (typeof base.options.beforeMove === "function") {
603
+ base.options.beforeMove.apply(this, [base.$elem]);
604
+ }
605
+ if (position >= base.maximumItem) {
606
+ position = base.maximumItem;
607
+ } else if (position <= 0) {
608
+ position = 0;
609
+ }
610
+
611
+ base.currentItem = base.easingslider.currentItem = position;
612
+ if (base.options.transitionStyle !== false && drag !== "drag" && base.options.items === 1 && base.browser.support3d === true) {
613
+ base.swapSpeed(0);
614
+ if (base.browser.support3d === true) {
615
+ base.transition3d(base.positionsInArray[position]);
616
+ } else {
617
+ base.css2slide(base.positionsInArray[position], 1);
618
+ }
619
+ base.afterGo();
620
+ base.singleItemTransition();
621
+ return false;
622
+ }
623
+ goToPixel = base.positionsInArray[position];
624
+
625
+ if (base.browser.support3d === true) {
626
+ base.isCss3Finish = false;
627
+
628
+ if (speed === true) {
629
+ base.swapSpeed("paginationSpeed");
630
+ window.setTimeout(function () {
631
+ base.isCss3Finish = true;
632
+ }, base.options.paginationSpeed);
633
+
634
+ } else if (speed === "rewind") {
635
+ base.swapSpeed(base.options.rewindSpeed);
636
+ window.setTimeout(function () {
637
+ base.isCss3Finish = true;
638
+ }, base.options.rewindSpeed);
639
+
640
+ } else {
641
+ base.swapSpeed("slideSpeed");
642
+ window.setTimeout(function () {
643
+ base.isCss3Finish = true;
644
+ }, base.options.slideSpeed);
645
+ }
646
+ base.transition3d(goToPixel);
647
+ } else {
648
+ if (speed === true) {
649
+ base.css2slide(goToPixel, base.options.paginationSpeed);
650
+ } else if (speed === "rewind") {
651
+ base.css2slide(goToPixel, base.options.rewindSpeed);
652
+ } else {
653
+ base.css2slide(goToPixel, base.options.slideSpeed);
654
+ }
655
+ }
656
+ base.afterGo();
657
+ },
658
+
659
+ jumpTo : function (position) {
660
+ var base = this;
661
+ if (typeof base.options.beforeMove === "function") {
662
+ base.options.beforeMove.apply(this, [base.$elem]);
663
+ }
664
+ if (position >= base.maximumItem || position === -1) {
665
+ position = base.maximumItem;
666
+ } else if (position <= 0) {
667
+ position = 0;
668
+ }
669
+ base.swapSpeed(0);
670
+ if (base.browser.support3d === true) {
671
+ base.transition3d(base.positionsInArray[position]);
672
+ } else {
673
+ base.css2slide(base.positionsInArray[position], 1);
674
+ }
675
+ base.currentItem = base.easingslider.currentItem = position;
676
+ base.afterGo();
677
+ },
678
+
679
+ afterGo : function () {
680
+ var base = this;
681
+
682
+ base.prevArr.push(base.currentItem);
683
+ base.prevItem = base.easingslider.prevItem = base.prevArr[base.prevArr.length - 2];
684
+ base.prevArr.shift(0);
685
+
686
+ if (base.prevItem !== base.currentItem) {
687
+ base.checkPagination();
688
+ base.checkNavigation();
689
+ base.eachMoveUpdate();
690
+
691
+ if (base.options.autoPlay !== false) {
692
+ base.checkAp();
693
+ }
694
+ }
695
+ if (typeof base.options.afterMove === "function" && base.prevItem !== base.currentItem) {
696
+ base.options.afterMove.apply(this, [base.$elem]);
697
+ }
698
+ },
699
+
700
+ stop : function () {
701
+ var base = this;
702
+ base.apStatus = "stop";
703
+ window.clearInterval(base.autoPlayInterval);
704
+ },
705
+
706
+ checkAp : function () {
707
+ var base = this;
708
+ if (base.apStatus !== "stop") {
709
+ base.play();
710
+ }
711
+ },
712
+
713
+ play : function () {
714
+ var base = this;
715
+ base.apStatus = "play";
716
+ if (base.options.autoPlay === false) {
717
+ return false;
718
+ }
719
+ window.clearInterval(base.autoPlayInterval);
720
+ base.autoPlayInterval = window.setInterval(function () {
721
+ base.next(true);
722
+ }, base.options.autoPlay);
723
+ },
724
+
725
+ swapSpeed : function (action) {
726
+ var base = this;
727
+ if (action === "slideSpeed") {
728
+ base.$easingsliderWrapper.css(base.addCssSpeed(base.options.slideSpeed));
729
+ } else if (action === "paginationSpeed") {
730
+ base.$easingsliderWrapper.css(base.addCssSpeed(base.options.paginationSpeed));
731
+ } else if (typeof action !== "string") {
732
+ base.$easingsliderWrapper.css(base.addCssSpeed(action));
733
+ }
734
+ },
735
+
736
+ addCssSpeed : function (speed) {
737
+ return {
738
+ "-webkit-transition": "all " + speed + "ms ease",
739
+ "-moz-transition": "all " + speed + "ms ease",
740
+ "-o-transition": "all " + speed + "ms ease",
741
+ "transition": "all " + speed + "ms ease"
742
+ };
743
+ },
744
+
745
+ removeTransition : function () {
746
+ return {
747
+ "-webkit-transition": "",
748
+ "-moz-transition": "",
749
+ "-o-transition": "",
750
+ "transition": ""
751
+ };
752
+ },
753
+
754
+ doTranslate : function (pixels) {
755
+ return {
756
+ "-webkit-transform": "translate3d(" + pixels + "px, 0px, 0px)",
757
+ "-moz-transform": "translate3d(" + pixels + "px, 0px, 0px)",
758
+ "-o-transform": "translate3d(" + pixels + "px, 0px, 0px)",
759
+ "-ms-transform": "translate3d(" + pixels + "px, 0px, 0px)",
760
+ "transform": "translate3d(" + pixels + "px, 0px,0px)"
761
+ };
762
+ },
763
+
764
+ transition3d : function (value) {
765
+ var base = this;
766
+ base.$easingsliderWrapper.css(base.doTranslate(value));
767
+ },
768
+
769
+ css2move : function (value) {
770
+ var base = this;
771
+ base.$easingsliderWrapper.css({"left" : value});
772
+ },
773
+
774
+ css2slide : function (value, speed) {
775
+ var base = this;
776
+
777
+ base.isCssFinish = false;
778
+ base.$easingsliderWrapper.stop(true, true).animate({
779
+ "left" : value
780
+ }, {
781
+ duration : speed || base.options.slideSpeed,
782
+ complete : function () {
783
+ base.isCssFinish = true;
784
+ }
785
+ });
786
+ },
787
+
788
+ checkBrowser : function () {
789
+ var base = this,
790
+ translate3D = "translate3d(0px, 0px, 0px)",
791
+ tempElem = document.createElement("div"),
792
+ regex,
793
+ asSupport,
794
+ support3d,
795
+ isTouch;
796
+
797
+ tempElem.style.cssText = " -moz-transform:" + translate3D +
798
+ "; -ms-transform:" + translate3D +
799
+ "; -o-transform:" + translate3D +
800
+ "; -webkit-transform:" + translate3D +
801
+ "; transform:" + translate3D;
802
+ regex = /translate3d\(0px, 0px, 0px\)/g;
803
+ asSupport = tempElem.style.cssText.match(regex);
804
+ support3d = (asSupport !== null && asSupport.length === 1);
805
+
806
+ isTouch = "ontouchstart" in window || window.navigator.msMaxTouchPoints;
807
+
808
+ base.browser = {
809
+ "support3d" : support3d,
810
+ "isTouch" : isTouch
811
+ };
812
+ },
813
+
814
+ moveEvents : function () {
815
+ var base = this;
816
+ if (base.options.mouseDrag !== false || base.options.touchDrag !== false) {
817
+ base.gestures();
818
+ base.disabledEvents();
819
+ }
820
+ },
821
+
822
+ eventTypes : function () {
823
+ var base = this,
824
+ types = ["s", "e", "x"];
825
+
826
+ base.ev_types = {};
827
+
828
+ if (base.options.mouseDrag === true && base.options.touchDrag === true) {
829
+ types = [
830
+ "touchstart.easingslider mousedown.easingslider",
831
+ "touchmove.easingslider mousemove.easingslider",
832
+ "touchend.easingslider touchcancel.easingslider mouseup.easingslider"
833
+ ];
834
+ } else if (base.options.mouseDrag === false && base.options.touchDrag === true) {
835
+ types = [
836
+ "touchstart.easingslider",
837
+ "touchmove.easingslider",
838
+ "touchend.easingslider touchcancel.easingslider"
839
+ ];
840
+ } else if (base.options.mouseDrag === true && base.options.touchDrag === false) {
841
+ types = [
842
+ "mousedown.easingslider",
843
+ "mousemove.easingslider",
844
+ "mouseup.easingslider"
845
+ ];
846
+ }
847
+
848
+ base.ev_types.start = types[0];
849
+ base.ev_types.move = types[1];
850
+ base.ev_types.end = types[2];
851
+ },
852
+
853
+ disabledEvents : function () {
854
+ var base = this;
855
+ base.$elem.on("dragstart.easingslider", function (event) { event.preventDefault(); });
856
+ base.$elem.on("mousedown.disableTextSelect", function (e) {
857
+ return $(e.target).is('input, textarea, select, option');
858
+ });
859
+ },
860
+
861
+ gestures : function () {
862
+ /*jslint unparam: true*/
863
+ var base = this,
864
+ locals = {
865
+ offsetX : 0,
866
+ offsetY : 0,
867
+ baseElWidth : 0,
868
+ relativePos : 0,
869
+ position: null,
870
+ minSwipe : null,
871
+ maxSwipe: null,
872
+ sliding : null,
873
+ dargging: null,
874
+ targetElement : null
875
+ };
876
+
877
+ base.isCssFinish = true;
878
+
879
+ function getTouches(event) {
880
+ if (event.touches !== undefined) {
881
+ return {
882
+ x : event.touches[0].pageX,
883
+ y : event.touches[0].pageY
884
+ };
885
+ }
886
+
887
+ if (event.touches === undefined) {
888
+ if (event.pageX !== undefined) {
889
+ return {
890
+ x : event.pageX,
891
+ y : event.pageY
892
+ };
893
+ }
894
+ if (event.pageX === undefined) {
895
+ return {
896
+ x : event.clientX,
897
+ y : event.clientY
898
+ };
899
+ }
900
+ }
901
+ }
902
+
903
+ function swapEvents(type) {
904
+ if (type === "on") {
905
+ $(document).on(base.ev_types.move, dragMove);
906
+ $(document).on(base.ev_types.end, dragEnd);
907
+ } else if (type === "off") {
908
+ $(document).off(base.ev_types.move);
909
+ $(document).off(base.ev_types.end);
910
+ }
911
+ }
912
+
913
+ function dragStart(event) {
914
+ var ev = event.originalEvent || event || window.event,
915
+ position;
916
+
917
+ if (ev.which === 3) {
918
+ return false;
919
+ }
920
+ if (base.itemsAmount <= base.options.items) {
921
+ return;
922
+ }
923
+ if (base.isCssFinish === false && !base.options.dragBeforeAnimFinish) {
924
+ return false;
925
+ }
926
+ if (base.isCss3Finish === false && !base.options.dragBeforeAnimFinish) {
927
+ return false;
928
+ }
929
+
930
+ if (base.options.autoPlay !== false) {
931
+ window.clearInterval(base.autoPlayInterval);
932
+ }
933
+
934
+ if (base.browser.isTouch !== true && !base.$easingsliderWrapper.hasClass("grabbing")) {
935
+ base.$easingsliderWrapper.addClass("grabbing");
936
+ }
937
+
938
+ base.newPosX = 0;
939
+ base.newRelativeX = 0;
940
+
941
+ $(this).css(base.removeTransition());
942
+
943
+ position = $(this).position();
944
+ locals.relativePos = position.left;
945
+
946
+ locals.offsetX = getTouches(ev).x - position.left;
947
+ locals.offsetY = getTouches(ev).y - position.top;
948
+
949
+ swapEvents("on");
950
+
951
+ locals.sliding = false;
952
+ locals.targetElement = ev.target || ev.srcElement;
953
+ }
954
+
955
+ function dragMove(event) {
956
+ var ev = event.originalEvent || event || window.event,
957
+ minSwipe,
958
+ maxSwipe;
959
+
960
+ base.newPosX = getTouches(ev).x - locals.offsetX;
961
+ base.newPosY = getTouches(ev).y - locals.offsetY;
962
+ base.newRelativeX = base.newPosX - locals.relativePos;
963
+
964
+ if (typeof base.options.startDragging === "function" && locals.dragging !== true && base.newRelativeX !== 0) {
965
+ locals.dragging = true;
966
+ base.options.startDragging.apply(base, [base.$elem]);
967
+ }
968
+
969
+ if ((base.newRelativeX > 8 || base.newRelativeX < -8) && (base.browser.isTouch === true)) {
970
+ if (ev.preventDefault !== undefined) {
971
+ ev.preventDefault();
972
+ } else {
973
+ ev.returnValue = false;
974
+ }
975
+ locals.sliding = true;
976
+ }
977
+
978
+ if ((base.newPosY > 10 || base.newPosY < -10) && locals.sliding === false) {
979
+ $(document).off("touchmove.easingslider");
980
+ }
981
+
982
+ minSwipe = function () {
983
+ return base.newRelativeX / 5;
984
+ };
985
+
986
+ maxSwipe = function () {
987
+ return base.maximumPixels + base.newRelativeX / 5;
988
+ };
989
+
990
+ base.newPosX = Math.max(Math.min(base.newPosX, minSwipe()), maxSwipe());
991
+ if (base.browser.support3d === true) {
992
+ base.transition3d(base.newPosX);
993
+ } else {
994
+ base.css2move(base.newPosX);
995
+ }
996
+ }
997
+
998
+ function dragEnd(event) {
999
+ var ev = event.originalEvent || event || window.event,
1000
+ newPosition,
1001
+ handlers,
1002
+ easingsliderStopEvent;
1003
+
1004
+ ev.target = ev.target || ev.srcElement;
1005
+
1006
+ locals.dragging = false;
1007
+
1008
+ if (base.browser.isTouch !== true) {
1009
+ base.$easingsliderWrapper.removeClass("grabbing");
1010
+ }
1011
+
1012
+ if (base.newRelativeX < 0) {
1013
+ base.dragDirection = base.easingslider.dragDirection = "left";
1014
+ } else {
1015
+ base.dragDirection = base.easingslider.dragDirection = "right";
1016
+ }
1017
+
1018
+ if (base.newRelativeX !== 0) {
1019
+ newPosition = base.getNewPosition();
1020
+ base.goTo(newPosition, false, "drag");
1021
+ if (locals.targetElement === ev.target && base.browser.isTouch !== true) {
1022
+ $(ev.target).on("click.disable", function (ev) {
1023
+ ev.stopImmediatePropagation();
1024
+ ev.stopPropagation();
1025
+ ev.preventDefault();
1026
+ $(ev.target).off("click.disable");
1027
+ });
1028
+ handlers = $._data(ev.target, "events").click;
1029
+ easingsliderStopEvent = handlers.pop();
1030
+ handlers.splice(0, 0, easingsliderStopEvent);
1031
+ }
1032
+ }
1033
+ swapEvents("off");
1034
+ }
1035
+ base.$elem.on(base.ev_types.start, ".easingslider-wrapper", dragStart);
1036
+ },
1037
+
1038
+ getNewPosition : function () {
1039
+ var base = this,
1040
+ newPosition = base.closestItem();
1041
+
1042
+ if (newPosition > base.maximumItem) {
1043
+ base.currentItem = base.maximumItem;
1044
+ newPosition = base.maximumItem;
1045
+ } else if (base.newPosX >= 0) {
1046
+ newPosition = 0;
1047
+ base.currentItem = 0;
1048
+ }
1049
+ return newPosition;
1050
+ },
1051
+ closestItem : function () {
1052
+ var base = this,
1053
+ array = base.options.scrollPerPage === true ? base.pagesInArray : base.positionsInArray,
1054
+ goal = base.newPosX,
1055
+ closest = null;
1056
+
1057
+ $.each(array, function (i, v) {
1058
+ if (goal - (base.itemWidth / 20) > array[i + 1] && goal - (base.itemWidth / 20) < v && base.moveDirection() === "left") {
1059
+ closest = v;
1060
+ if (base.options.scrollPerPage === true) {
1061
+ base.currentItem = $.inArray(closest, base.positionsInArray);
1062
+ } else {
1063
+ base.currentItem = i;
1064
+ }
1065
+ } else if (goal + (base.itemWidth / 20) < v && goal + (base.itemWidth / 20) > (array[i + 1] || array[i] - base.itemWidth) && base.moveDirection() === "right") {
1066
+ if (base.options.scrollPerPage === true) {
1067
+ closest = array[i + 1] || array[array.length - 1];
1068
+ base.currentItem = $.inArray(closest, base.positionsInArray);
1069
+ } else {
1070
+ closest = array[i + 1];
1071
+ base.currentItem = i + 1;
1072
+ }
1073
+ }
1074
+ });
1075
+ return base.currentItem;
1076
+ },
1077
+
1078
+ moveDirection : function () {
1079
+ var base = this,
1080
+ direction;
1081
+ if (base.newRelativeX < 0) {
1082
+ direction = "right";
1083
+ base.playDirection = "next";
1084
+ } else {
1085
+ direction = "left";
1086
+ base.playDirection = "prev";
1087
+ }
1088
+ return direction;
1089
+ },
1090
+
1091
+ customEvents : function () {
1092
+ /*jslint unparam: true*/
1093
+ var base = this;
1094
+ base.$elem.on("easingslider.next", function () {
1095
+ base.next();
1096
+ });
1097
+ base.$elem.on("easingslider.prev", function () {
1098
+ base.prev();
1099
+ });
1100
+ base.$elem.on("easingslider.play", function (event, speed) {
1101
+ base.options.autoPlay = speed;
1102
+ base.play();
1103
+ base.hoverStatus = "play";
1104
+ });
1105
+ base.$elem.on("easingslider.stop", function () {
1106
+ base.stop();
1107
+ base.hoverStatus = "stop";
1108
+ });
1109
+ base.$elem.on("easingslider.goTo", function (event, item) {
1110
+ base.goTo(item);
1111
+ });
1112
+ base.$elem.on("easingslider.jumpTo", function (event, item) {
1113
+ base.jumpTo(item);
1114
+ });
1115
+ },
1116
+
1117
+ stopOnHover : function () {
1118
+ var base = this;
1119
+ if (base.options.stopOnHover === true && base.browser.isTouch !== true && base.options.autoPlay !== false) {
1120
+ base.$elem.on("mouseover", function () {
1121
+ base.stop();
1122
+ });
1123
+ base.$elem.on("mouseout", function () {
1124
+ if (base.hoverStatus !== "stop") {
1125
+ base.play();
1126
+ }
1127
+ });
1128
+ }
1129
+ },
1130
+
1131
+ lazyLoad : function () {
1132
+ var base = this,
1133
+ i,
1134
+ $item,
1135
+ itemNumber,
1136
+ $lazyImg,
1137
+ follow;
1138
+
1139
+ if (base.options.lazyLoad === false) {
1140
+ return false;
1141
+ }
1142
+ for (i = 0; i < base.itemsAmount; i += 1) {
1143
+ $item = $(base.$easingsliderItems[i]);
1144
+
1145
+ if ($item.data("easingslider-loaded") === "loaded") {
1146
+ continue;
1147
+ }
1148
+
1149
+ itemNumber = $item.data("easingslider-item");
1150
+ $lazyImg = $item.find(".easingslider-lazy");
1151
+
1152
+ if (typeof $lazyImg.data("src") !== "string") {
1153
+ $item.data("easingslider-loaded", "loaded");
1154
+ continue;
1155
+ }
1156
+ if ($item.data("easingslider-loaded") === undefined) {
1157
+ $lazyImg.hide();
1158
+ $item.addClass("loading").data("easingslider-loaded", "checked");
1159
+ }
1160
+ if (base.options.lazyFollow === true) {
1161
+ follow = itemNumber >= base.currentItem;
1162
+ } else {
1163
+ follow = true;
1164
+ }
1165
+ if (follow && itemNumber < base.currentItem + base.options.items && $lazyImg.length) {
1166
+ base.lazyPreload($item, $lazyImg);
1167
+ }
1168
+ }
1169
+ },
1170
+
1171
+ lazyPreload : function ($item, $lazyImg) {
1172
+ var base = this,
1173
+ iterations = 0,
1174
+ isBackgroundImg;
1175
+
1176
+ if ($lazyImg.prop("tagName") === "DIV") {
1177
+ $lazyImg.css("background-image", "url(" + $lazyImg.data("src") + ")");
1178
+ isBackgroundImg = true;
1179
+ } else {
1180
+ $lazyImg[0].src = $lazyImg.data("src");
1181
+ }
1182
+
1183
+ function showImage() {
1184
+ $item.data("easingslider-loaded", "loaded").removeClass("loading");
1185
+ $lazyImg.removeAttr("data-src");
1186
+ if (base.options.lazyEffect === "fade") {
1187
+ $lazyImg.fadeIn(400);
1188
+ } else {
1189
+ $lazyImg.show();
1190
+ }
1191
+ if (typeof base.options.afterLazyLoad === "function") {
1192
+ base.options.afterLazyLoad.apply(this, [base.$elem]);
1193
+ }
1194
+ }
1195
+
1196
+ function checkLazyImage() {
1197
+ iterations += 1;
1198
+ if (base.completeImg($lazyImg.get(0)) || isBackgroundImg === true) {
1199
+ showImage();
1200
+ } else if (iterations <= 100) {//if image loads in less than 10 seconds
1201
+ window.setTimeout(checkLazyImage, 100);
1202
+ } else {
1203
+ showImage();
1204
+ }
1205
+ }
1206
+
1207
+ checkLazyImage();
1208
+ },
1209
+
1210
+ autoHeight : function () {
1211
+ var base = this,
1212
+ $currentimg = $(base.$easingsliderItems[base.currentItem]).find("img"),
1213
+ iterations;
1214
+
1215
+ function addHeight() {
1216
+ var $currentItem = $(base.$easingsliderItems[base.currentItem]).height();
1217
+ base.wrapperOuter.css("height", $currentItem + "px");
1218
+ if (!base.wrapperOuter.hasClass("autoHeight")) {
1219
+ window.setTimeout(function () {
1220
+ base.wrapperOuter.addClass("autoHeight");
1221
+ }, 0);
1222
+ }
1223
+ }
1224
+
1225
+ function checkImage() {
1226
+ iterations += 1;
1227
+ if (base.completeImg($currentimg.get(0))) {
1228
+ addHeight();
1229
+ } else if (iterations <= 100) { //if image loads in less than 10 seconds
1230
+ window.setTimeout(checkImage, 100);
1231
+ } else {
1232
+ base.wrapperOuter.css("height", ""); //Else remove height attribute
1233
+ }
1234
+ }
1235
+
1236
+ if ($currentimg.get(0) !== undefined) {
1237
+ iterations = 0;
1238
+ checkImage();
1239
+ } else {
1240
+ addHeight();
1241
+ }
1242
+ },
1243
+
1244
+ completeImg : function (img) {
1245
+ var naturalWidthType;
1246
+
1247
+ if (!img.complete) {
1248
+ return false;
1249
+ }
1250
+ naturalWidthType = typeof img.naturalWidth;
1251
+ if (naturalWidthType !== "undefined" && img.naturalWidth === 0) {
1252
+ return false;
1253
+ }
1254
+ return true;
1255
+ },
1256
+
1257
+ onVisibleItems : function () {
1258
+ var base = this,
1259
+ i;
1260
+
1261
+ if (base.options.addClassActive === true) {
1262
+ base.$easingsliderItems.removeClass("active");
1263
+ }
1264
+ base.visibleItems = [];
1265
+ for (i = base.currentItem; i < base.currentItem + base.options.items; i += 1) {
1266
+ base.visibleItems.push(i);
1267
+
1268
+ if (base.options.addClassActive === true) {
1269
+ $(base.$easingsliderItems[i]).addClass("active");
1270
+ }
1271
+ }
1272
+ base.easingslider.visibleItems = base.visibleItems;
1273
+ },
1274
+
1275
+ transitionTypes : function (className) {
1276
+ var base = this;
1277
+ //Currently available: "fade", "backSlide", "goDown", "fadeUp"
1278
+ base.outClass = "easingslider-" + className + "-out";
1279
+ base.inClass = "easingslider-" + className + "-in";
1280
+ },
1281
+
1282
+ singleItemTransition : function () {
1283
+ var base = this,
1284
+ outClass = base.outClass,
1285
+ inClass = base.inClass,
1286
+ $currentItem = base.$easingsliderItems.eq(base.currentItem),
1287
+ $prevItem = base.$easingsliderItems.eq(base.prevItem),
1288
+ prevPos = Math.abs(base.positionsInArray[base.currentItem]) + base.positionsInArray[base.prevItem],
1289
+ origin = Math.abs(base.positionsInArray[base.currentItem]) + base.itemWidth / 2,
1290
+ animEnd = 'webkitAnimationEnd oAnimationEnd MSAnimationEnd animationend';
1291
+
1292
+ base.isTransition = true;
1293
+
1294
+ base.$easingsliderWrapper
1295
+ .addClass('easingslider-origin')
1296
+ .css({
1297
+ "-webkit-transform-origin" : origin + "px",
1298
+ "-moz-perspective-origin" : origin + "px",
1299
+ "perspective-origin" : origin + "px"
1300
+ });
1301
+ function transStyles(prevPos) {
1302
+ return {
1303
+ "position" : "relative",
1304
+ "left" : prevPos + "px"
1305
+ };
1306
+ }
1307
+
1308
+ $prevItem
1309
+ .css(transStyles(prevPos, 10))
1310
+ .addClass(outClass)
1311
+ .on(animEnd, function () {
1312
+ base.endPrev = true;
1313
+ $prevItem.off(animEnd);
1314
+ base.clearTransStyle($prevItem, outClass);
1315
+ });
1316
+
1317
+ $currentItem
1318
+ .addClass(inClass)
1319
+ .on(animEnd, function () {
1320
+ base.endCurrent = true;
1321
+ $currentItem.off(animEnd);
1322
+ base.clearTransStyle($currentItem, inClass);
1323
+ });
1324
+ },
1325
+
1326
+ clearTransStyle : function (item, classToRemove) {
1327
+ var base = this;
1328
+ item.css({
1329
+ "position" : "",
1330
+ "left" : ""
1331
+ }).removeClass(classToRemove);
1332
+
1333
+ if (base.endPrev && base.endCurrent) {
1334
+ base.$easingsliderWrapper.removeClass('easingslider-origin');
1335
+ base.endPrev = false;
1336
+ base.endCurrent = false;
1337
+ base.isTransition = false;
1338
+ }
1339
+ },
1340
+
1341
+ easingsliderStatus : function () {
1342
+ var base = this;
1343
+ base.easingslider = {
1344
+ "userOptions" : base.userOptions,
1345
+ "baseElement" : base.$elem,
1346
+ "userItems" : base.$userItems,
1347
+ "easingsliderItems" : base.$easingsliderItems,
1348
+ "currentItem" : base.currentItem,
1349
+ "prevItem" : base.prevItem,
1350
+ "visibleItems" : base.visibleItems,
1351
+ "isTouch" : base.browser.isTouch,
1352
+ "browser" : base.browser,
1353
+ "dragDirection" : base.dragDirection
1354
+ };
1355
+ },
1356
+
1357
+ clearEvents : function () {
1358
+ var base = this;
1359
+ base.$elem.off(".easingslider easingslider mousedown.disableTextSelect");
1360
+ $(document).off(".easingslider easingslider");
1361
+ $(window).off("resize", base.resizer);
1362
+ },
1363
+
1364
+ unWrap : function () {
1365
+ var base = this;
1366
+ if (base.$elem.children().length !== 0) {
1367
+ base.$easingsliderWrapper.unwrap();
1368
+ base.$userItems.unwrap().unwrap();
1369
+ if (base.easingsliderControls) {
1370
+ base.easingsliderControls.remove();
1371
+ }
1372
+ }
1373
+ base.clearEvents();
1374
+ base.$elem
1375
+ .attr("style", base.$elem.data("easingslider-originalStyles") || "")
1376
+ .attr("class", base.$elem.data("easingslider-originalClasses"));
1377
+ },
1378
+
1379
+ destroy : function () {
1380
+ var base = this;
1381
+ base.stop();
1382
+ window.clearInterval(base.checkVisible);
1383
+ base.unWrap();
1384
+ base.$elem.removeData();
1385
+ },
1386
+
1387
+ reinit : function (newOptions) {
1388
+ var base = this,
1389
+ options = $.extend({}, base.userOptions, newOptions);
1390
+ base.unWrap();
1391
+ base.init(options, base.$elem);
1392
+ },
1393
+
1394
+ addItem : function (htmlString, targetPosition) {
1395
+ var base = this,
1396
+ position;
1397
+
1398
+ if (!htmlString) {return false; }
1399
+
1400
+ if (base.$elem.children().length === 0) {
1401
+ base.$elem.append(htmlString);
1402
+ base.setVars();
1403
+ return false;
1404
+ }
1405
+ base.unWrap();
1406
+ if (targetPosition === undefined || targetPosition === -1) {
1407
+ position = -1;
1408
+ } else {
1409
+ position = targetPosition;
1410
+ }
1411
+ if (position >= base.$userItems.length || position === -1) {
1412
+ base.$userItems.eq(-1).after(htmlString);
1413
+ } else {
1414
+ base.$userItems.eq(position).before(htmlString);
1415
+ }
1416
+
1417
+ base.setVars();
1418
+ },
1419
+
1420
+ removeItem : function (targetPosition) {
1421
+ var base = this,
1422
+ position;
1423
+
1424
+ if (base.$elem.children().length === 0) {
1425
+ return false;
1426
+ }
1427
+ if (targetPosition === undefined || targetPosition === -1) {
1428
+ position = -1;
1429
+ } else {
1430
+ position = targetPosition;
1431
+ }
1432
+
1433
+ base.unWrap();
1434
+ base.$userItems.eq(position).remove();
1435
+ base.setVars();
1436
+ }
1437
+
1438
+ };
1439
+
1440
+ $.fn.easingSlider = function (options) {
1441
+ return this.each(function () {
1442
+ if ($(this).data("easingslider-init") === true) {
1443
+ return false;
1444
+ }
1445
+ $(this).data("easingslider-init", true);
1446
+ var carousel = Object.create(Carousel);
1447
+ carousel.init(options, this);
1448
+ $.data(this, "easingSlider", carousel);
1449
+ });
1450
+ };
1451
+
1452
+ $.fn.easingSlider.options = {
1453
+
1454
+ items : 5,
1455
+ itemsCustom : false,
1456
+ itemsDesktop : [1199, 4],
1457
+ itemsDesktopSmall : [979, 3],
1458
+ itemsTablet : [768, 2],
1459
+ itemsTabletSmall : false,
1460
+ itemsMobile : [479, 1],
1461
+ singleItem : false,
1462
+ itemsScaleUp : false,
1463
+
1464
+ slideSpeed : 200,
1465
+ paginationSpeed : 800,
1466
+ rewindSpeed : 1000,
1467
+
1468
+ autoPlay : false,
1469
+ stopOnHover : false,
1470
+
1471
+ navigation : false,
1472
+ navigationText : ["prev", "next"],
1473
+ rewindNav : true,
1474
+ scrollPerPage : false,
1475
+
1476
+ pagination : true,
1477
+ paginationNumbers : false,
1478
+
1479
+ responsive : true,
1480
+ responsiveRefreshRate : 200,
1481
+ responsiveBaseWidth : window,
1482
+
1483
+ baseClass : "easingslider",
1484
+ theme : "easingslider-theme",
1485
+
1486
+ lazyLoad : false,
1487
+ lazyFollow : true,
1488
+ lazyEffect : "fade",
1489
+
1490
+ autoHeight : false,
1491
+
1492
+ jsonPath : false,
1493
+ jsonSuccess : false,
1494
+
1495
+ dragBeforeAnimFinish : true,
1496
+ mouseDrag : true,
1497
+ touchDrag : true,
1498
+
1499
+ addClassActive : false,
1500
+ transitionStyle : false,
1501
+
1502
+ beforeUpdate : false,
1503
+ afterUpdate : false,
1504
+ beforeInit : false,
1505
+ afterInit : false,
1506
+ beforeMove : false,
1507
+ afterMove : false,
1508
+ afterAction : false,
1509
+ startDragging : false,
1510
+ afterLazyLoad: false
1511
+ };
1512
+ }(jQuery, window, document));
1513
+ ;(function($) {
1514
+
1515
+ /**
1516
+ * jQuery Easing Slider
1517
+ *
1518
+ * This is essentially a container for our interactions with Owl Carousel, aliased as `$.easingSlider` to avoid conflicts.
1519
+ * We're relying on it as our third-party slider script, plus some additional functionality to enhance.
1520
+ */
1521
+ $.EasingSlider = function(el) {
1522
+
1523
+ // Core variables
1524
+ var base = this;
1525
+
1526
+ // Establish our elements
1527
+ base.el = el;
1528
+ base.$el = $(base.el);
1529
+ base.$wrapper = base.$el.find('.easingslider-wrapper');
1530
+ base.$slides = base.$el.find('.easingslider-slide');
1531
+ base.$images = base.$el.find('.easingslider-image');
1532
+
1533
+ // Get options
1534
+ base.options = window['EasingSlider'+ base.$el.attr('data-id')];
1535
+
1536
+ // Determine click event
1537
+ base._clickEvent = ( 'ontouchstart' in document.documentElement ) ? 'touchstart' : 'click';
1538
+
1539
+ // Store our data for external access
1540
+ base.$el.data('easingslider', base);
1541
+
1542
+ /**
1543
+ * Initiates the slider
1544
+ */
1545
+ base.initSlider = function() {
1546
+
1547
+ // Initiate Owl Carousel (aliased as $.easingSlider to avoid conflicts)
1548
+ base.$el.easingSlider($.extend(base.options, {
1549
+ afterInit: function() {
1550
+ base._maybeResize();
1551
+ },
1552
+ afterUpdate: function() {
1553
+ base._maybeResize();
1554
+ },
1555
+ afterAction: function() {
1556
+ base.$el.trigger('changeSlide', this.currentItem);
1557
+ }
1558
+ }));
1559
+
1560
+ };
1561
+
1562
+ /**
1563
+ * Resizes the slider if aspect ratio is enabled
1564
+ */
1565
+ base._maybeResize = function() {
1566
+
1567
+ // Resize if maintaining aspect ratio
1568
+ if ( base.$el.hasClass('easingslider-aspect-ratio') ) {
1569
+ base.doResize();
1570
+ }
1571
+
1572
+ return base;
1573
+
1574
+ };
1575
+
1576
+ /**
1577
+ * Executes a resize
1578
+ */
1579
+ base.doResize = function() {
1580
+
1581
+ // Get the current width & wrapper width
1582
+ var currentWidth = base.$el.outerWidth();
1583
+
1584
+ // Get the outer wrapper
1585
+ var outerWrapper = base.$el.find('.easingslider-wrapper-outer');
1586
+
1587
+ // If it has changed, resize the height to match.
1588
+ if ( currentWidth <= base.options.width ) {
1589
+
1590
+ // Using the default slider width, let's calculate the percentage change and thus calculate the new height.
1591
+ var newHeight = Math.floor((currentWidth / base.options.width) * base.options.height);
1592
+
1593
+ // Set the wrapper height
1594
+ base.$el.css({ 'height': newHeight +'px' });
1595
+ base.$wrapper.css({ 'height': newHeight +'px' });
1596
+ base.$images.css({ 'max-height': newHeight +'px' });
1597
+
1598
+ } else {
1599
+
1600
+ // Set image height(s) only
1601
+ base.$el.css({ 'height': base.options.height +'px' });
1602
+ base.$wrapper.css({ 'height': base.options.height +'px' });
1603
+ base.$images.css({ 'max-height': base.options.height +'px' });
1604
+
1605
+ }
1606
+
1607
+ // Prevent subpixel rendering by rounding width
1608
+ outerWrapper.css({ 'width': Math.floor(outerWrapper.outerWidth()) +'px' });
1609
+
1610
+ return base;
1611
+
1612
+ };
1613
+
1614
+ // Initialize plugin
1615
+ base.initSlider();
1616
+
1617
+ };
1618
+
1619
+ /**
1620
+ * Initiate slider(s)
1621
+ */
1622
+ $.fn.EasingSlider = function() {
1623
+ return this.each(function() {
1624
+ new $.EasingSlider(this);
1625
+ });
1626
+ };
1627
+
1628
+ /**
1629
+ * Let's go!
1630
+ */
1631
+ $(document).ready(function() {
1632
+ $('.easingslider').EasingSlider();
1633
+ });
1634
+
1635
+ })(jQuery);
assets/js/public.min.js ADDED
@@ -0,0 +1 @@
 
1
+ "function"!=typeof Object.create&&(Object.create=function(a){function b(){}return b.prototype=a,new b}),function(a,b,c){var d={init:function(b,c){var d=this;d.$elem=a(c),d.options=a.extend({},a.fn.easingSlider.options,d.$elem.data(),b),d.userOptions=b,d.loadContent()},loadContent:function(){function b(a){var b,c="";if("function"==typeof d.options.jsonSuccess)d.options.jsonSuccess.apply(this,[a]);else{for(b in a.easingslider)a.easingslider.hasOwnProperty(b)&&(c+=a.easingslider[b].item);d.$elem.html(c)}d.logIn()}var c,d=this;"function"==typeof d.options.beforeInit&&d.options.beforeInit.apply(this,[d.$elem]),"string"==typeof d.options.jsonPath?(c=d.options.jsonPath,a.getJSON(c,b)):d.logIn()},logIn:function(){var a=this;a.$elem.data("easingslider-originalStyles",a.$elem.attr("style")).data("easingslider-originalClasses",a.$elem.attr("class")),a.$elem.css({opacity:0}),a.orignalItems=a.options.items,a.checkBrowser(),a.wrapperWidth=0,a.checkVisible=null,a.setVars()},setVars:function(){var a=this;return 0===a.$elem.children().length?!1:(a.baseClass(),a.eventTypes(),a.$userItems=a.$elem.children(),a.itemsAmount=a.$userItems.length,a.wrapItems(),a.$easingsliderItems=a.$elem.find(".easingslider-item"),a.$easingsliderWrapper=a.$elem.find(".easingslider-wrapper"),a.playDirection="next",a.prevItem=0,a.prevArr=[0],a.currentItem=0,a.customEvents(),void a.onStartup())},onStartup:function(){var a=this;a.updateItems(),a.calculateAll(),a.buildControls(),a.updateControls(),a.response(),a.moveEvents(),a.stopOnHover(),a.easingsliderStatus(),a.options.transitionStyle!==!1&&a.transitionTypes(a.options.transitionStyle),a.options.autoPlay===!0&&(a.options.autoPlay=5e3),a.play(),a.$elem.find(".easingslider-wrapper").css("display","block"),a.$elem.is(":visible")?a.$elem.css("opacity",1):a.watchVisibility(),a.onstartup=!1,a.eachMoveUpdate(),"function"==typeof a.options.afterInit&&a.options.afterInit.apply(this,[a.$elem])},eachMoveUpdate:function(){var a=this;a.options.lazyLoad===!0&&a.lazyLoad(),a.options.autoHeight===!0&&a.autoHeight(),a.onVisibleItems(),"function"==typeof a.options.afterAction&&a.options.afterAction.apply(this,[a.$elem])},updateVars:function(){var a=this;"function"==typeof a.options.beforeUpdate&&a.options.beforeUpdate.apply(this,[a.$elem]),a.watchVisibility(),a.updateItems(),a.calculateAll(),a.updatePosition(),a.updateControls(),a.eachMoveUpdate(),"function"==typeof a.options.afterUpdate&&a.options.afterUpdate.apply(this,[a.$elem])},reload:function(){var a=this;b.setTimeout(function(){a.updateVars()},0)},watchVisibility:function(){var a=this;return a.$elem.is(":visible")!==!1?!1:(a.$elem.css({opacity:0}),b.clearInterval(a.autoPlayInterval),b.clearInterval(a.checkVisible),void(a.checkVisible=b.setInterval(function(){a.$elem.is(":visible")&&(a.reload(),a.$elem.animate({opacity:1},200),b.clearInterval(a.checkVisible))},500)))},wrapItems:function(){var a=this;a.$userItems.wrapAll('<div class="easingslider-wrapper">').wrap('<div class="easingslider-item"></div>'),a.$elem.find(".easingslider-wrapper").wrap('<div class="easingslider-wrapper-outer">'),a.wrapperOuter=a.$elem.find(".easingslider-wrapper-outer"),a.$elem.css("display","block")},baseClass:function(){var a=this,b=a.$elem.hasClass(a.options.baseClass),c=a.$elem.hasClass(a.options.theme);b||a.$elem.addClass(a.options.baseClass),c||a.$elem.addClass(a.options.theme)},updateItems:function(){var b,c,d=this;if(d.options.responsive===!1)return!1;if(d.options.singleItem===!0)return d.options.items=d.orignalItems=1,d.options.itemsCustom=!1,d.options.itemsDesktop=!1,d.options.itemsDesktopSmall=!1,d.options.itemsTablet=!1,d.options.itemsTabletSmall=!1,d.options.itemsMobile=!1,!1;if(b=a(d.options.responsiveBaseWidth).width(),b>(d.options.itemsDesktop[0]||d.orignalItems)&&(d.options.items=d.orignalItems),d.options.itemsCustom!==!1)for(d.options.itemsCustom.sort(function(a,b){return a[0]-b[0]}),c=0;c<d.options.itemsCustom.length;c+=1)d.options.itemsCustom[c][0]<=b&&(d.options.items=d.options.itemsCustom[c][1]);else b<=d.options.itemsDesktop[0]&&d.options.itemsDesktop!==!1&&(d.options.items=d.options.itemsDesktop[1]),b<=d.options.itemsDesktopSmall[0]&&d.options.itemsDesktopSmall!==!1&&(d.options.items=d.options.itemsDesktopSmall[1]),b<=d.options.itemsTablet[0]&&d.options.itemsTablet!==!1&&(d.options.items=d.options.itemsTablet[1]),b<=d.options.itemsTabletSmall[0]&&d.options.itemsTabletSmall!==!1&&(d.options.items=d.options.itemsTabletSmall[1]),b<=d.options.itemsMobile[0]&&d.options.itemsMobile!==!1&&(d.options.items=d.options.itemsMobile[1]);d.options.items>d.itemsAmount&&d.options.itemsScaleUp===!0&&(d.options.items=d.itemsAmount)},response:function(){var c,d,e=this;return e.options.responsive!==!0?!1:(d=a(b).width(),e.resizer=function(){a(b).width()!==d&&(e.options.autoPlay!==!1&&b.clearInterval(e.autoPlayInterval),b.clearTimeout(c),c=b.setTimeout(function(){d=a(b).width(),e.updateVars()},e.options.responsiveRefreshRate))},void a(b).resize(e.resizer))},updatePosition:function(){var a=this;a.jumpTo(a.currentItem),a.options.autoPlay!==!1&&a.checkAp()},appendItemsSizes:function(){var b=this,c=0,d=b.itemsAmount-b.options.items;b.$easingsliderItems.each(function(e){var f=a(this);f.css({width:b.itemWidth}).data("easingslider-item",Number(e)),e%b.options.items!==0&&e!==d||e>d||(c+=1),f.data("easingslider-roundPages",c)})},appendWrapperSizes:function(){var a=this,b=a.$easingsliderItems.length*a.itemWidth;a.$easingsliderWrapper.css({width:2*b,left:0}),a.appendItemsSizes()},calculateAll:function(){var a=this;a.calculateWidth(),a.appendWrapperSizes(),a.loops(),a.max()},calculateWidth:function(){var a=this;a.itemWidth=Math.round(a.$elem.width()/a.options.items)},max:function(){var a=this,b=-1*(a.itemsAmount*a.itemWidth-a.options.items*a.itemWidth);return a.options.items>a.itemsAmount?(a.maximumItem=0,b=0,a.maximumPixels=0):(a.maximumItem=a.itemsAmount-a.options.items,a.maximumPixels=b),b},min:function(){return 0},loops:function(){var b,c,d,e=this,f=0,g=0;for(e.positionsInArray=[0],e.pagesInArray=[],b=0;b<e.itemsAmount;b+=1)g+=e.itemWidth,e.positionsInArray.push(-g),e.options.scrollPerPage===!0&&(c=a(e.$easingsliderItems[b]),d=c.data("easingslider-roundPages"),d!==f&&(e.pagesInArray[f]=e.positionsInArray[b],f=d))},buildControls:function(){var b=this;b.options.navigation!==!0&&b.options.pagination!==!0||(b.easingsliderControls=a('<div class="easingslider-controls"/>').toggleClass("clickable",!b.browser.isTouch).appendTo(b.$elem)),b.options.pagination===!0&&b.buildPagination(),b.options.navigation===!0&&b.buildButtons()},buildButtons:function(){var b=this,c=a('<div class="easingslider-buttons"/>');b.easingsliderControls.append(c),b.buttonPrev=a("<div/>",{"class":"easingslider-prev",html:b.options.navigationText[0]||""}),b.buttonNext=a("<div/>",{"class":"easingslider-next",html:b.options.navigationText[1]||""}),c.append(b.buttonPrev).append(b.buttonNext),c.on("touchstart.easingsliderControls mousedown.easingsliderControls",'div[class^="easingslider"]',function(a){a.preventDefault()}),c.on("touchend.easingsliderControls mouseup.easingsliderControls",'div[class^="easingslider"]',function(c){c.preventDefault(),a(this).hasClass("easingslider-next")?b.next():b.prev()})},buildPagination:function(){var b=this;b.paginationWrapper=a('<div class="easingslider-pagination"/>'),b.easingsliderControls.append(b.paginationWrapper),b.paginationWrapper.on("touchend.easingsliderControls mouseup.easingsliderControls",".easingslider-page",function(c){c.preventDefault(),Number(a(this).data("easingslider-page"))!==b.currentItem&&b.goTo(Number(a(this).data("easingslider-page")),!0)})},updatePagination:function(){var b,c,d,e,f,g,h=this;if(h.options.pagination===!1)return!1;for(h.paginationWrapper.html(""),b=0,c=h.itemsAmount-h.itemsAmount%h.options.items,e=0;e<h.itemsAmount;e+=1)e%h.options.items===0&&(b+=1,c===e&&(d=h.itemsAmount-h.options.items),f=a("<div/>",{"class":"easingslider-page"}),g=a("<span></span>",{text:h.options.paginationNumbers===!0?b:"","class":h.options.paginationNumbers===!0?"easingslider-numbers":""}),f.append(g),f.data("easingslider-page",c===e?d:e),f.data("easingslider-roundPages",b),h.paginationWrapper.append(f));h.checkPagination()},checkPagination:function(){var b=this;return b.options.pagination===!1?!1:void b.paginationWrapper.find(".easingslider-page").each(function(){a(this).data("easingslider-roundPages")===a(b.$easingsliderItems[b.currentItem]).data("easingslider-roundPages")&&(b.paginationWrapper.find(".easingslider-page").removeClass("active"),a(this).addClass("active"))})},checkNavigation:function(){var a=this;return a.options.navigation===!1?!1:void(a.options.rewindNav===!1&&(0===a.currentItem&&0===a.maximumItem?(a.buttonPrev.addClass("disabled"),a.buttonNext.addClass("disabled")):0===a.currentItem&&0!==a.maximumItem?(a.buttonPrev.addClass("disabled"),a.buttonNext.removeClass("disabled")):a.currentItem===a.maximumItem?(a.buttonPrev.removeClass("disabled"),a.buttonNext.addClass("disabled")):0!==a.currentItem&&a.currentItem!==a.maximumItem&&(a.buttonPrev.removeClass("disabled"),a.buttonNext.removeClass("disabled"))))},updateControls:function(){var a=this;a.updatePagination(),a.checkNavigation(),a.easingsliderControls&&(a.options.items>=a.itemsAmount?a.easingsliderControls.hide():a.easingsliderControls.show())},destroyControls:function(){var a=this;a.easingsliderControls&&a.easingsliderControls.remove()},next:function(a){var b=this;if(b.isTransition)return!1;if(b.currentItem+=b.options.scrollPerPage===!0?b.options.items:1,b.currentItem>b.maximumItem+(b.options.scrollPerPage===!0?b.options.items-1:0)){if(b.options.rewindNav!==!0)return b.currentItem=b.maximumItem,!1;b.currentItem=0,a="rewind"}b.goTo(b.currentItem,a)},prev:function(a){var b=this;if(b.isTransition)return!1;if(b.options.scrollPerPage===!0&&b.currentItem>0&&b.currentItem<b.options.items?b.currentItem=0:b.currentItem-=b.options.scrollPerPage===!0?b.options.items:1,b.currentItem<0){if(b.options.rewindNav!==!0)return b.currentItem=0,!1;b.currentItem=b.maximumItem,a="rewind"}b.goTo(b.currentItem,a)},goTo:function(a,c,d){var e,f=this;return f.isTransition?!1:("function"==typeof f.options.beforeMove&&f.options.beforeMove.apply(this,[f.$elem]),a>=f.maximumItem?a=f.maximumItem:0>=a&&(a=0),f.currentItem=f.easingslider.currentItem=a,f.options.transitionStyle!==!1&&"drag"!==d&&1===f.options.items&&f.browser.support3d===!0?(f.swapSpeed(0),f.browser.support3d===!0?f.transition3d(f.positionsInArray[a]):f.css2slide(f.positionsInArray[a],1),f.afterGo(),f.singleItemTransition(),!1):(e=f.positionsInArray[a],f.browser.support3d===!0?(f.isCss3Finish=!1,c===!0?(f.swapSpeed("paginationSpeed"),b.setTimeout(function(){f.isCss3Finish=!0},f.options.paginationSpeed)):"rewind"===c?(f.swapSpeed(f.options.rewindSpeed),b.setTimeout(function(){f.isCss3Finish=!0},f.options.rewindSpeed)):(f.swapSpeed("slideSpeed"),b.setTimeout(function(){f.isCss3Finish=!0},f.options.slideSpeed)),f.transition3d(e)):c===!0?f.css2slide(e,f.options.paginationSpeed):"rewind"===c?f.css2slide(e,f.options.rewindSpeed):f.css2slide(e,f.options.slideSpeed),void f.afterGo()))},jumpTo:function(a){var b=this;"function"==typeof b.options.beforeMove&&b.options.beforeMove.apply(this,[b.$elem]),a>=b.maximumItem||-1===a?a=b.maximumItem:0>=a&&(a=0),b.swapSpeed(0),b.browser.support3d===!0?b.transition3d(b.positionsInArray[a]):b.css2slide(b.positionsInArray[a],1),b.currentItem=b.easingslider.currentItem=a,b.afterGo()},afterGo:function(){var a=this;a.prevArr.push(a.currentItem),a.prevItem=a.easingslider.prevItem=a.prevArr[a.prevArr.length-2],a.prevArr.shift(0),a.prevItem!==a.currentItem&&(a.checkPagination(),a.checkNavigation(),a.eachMoveUpdate(),a.options.autoPlay!==!1&&a.checkAp()),"function"==typeof a.options.afterMove&&a.prevItem!==a.currentItem&&a.options.afterMove.apply(this,[a.$elem])},stop:function(){var a=this;a.apStatus="stop",b.clearInterval(a.autoPlayInterval)},checkAp:function(){var a=this;"stop"!==a.apStatus&&a.play()},play:function(){var a=this;return a.apStatus="play",a.options.autoPlay===!1?!1:(b.clearInterval(a.autoPlayInterval),void(a.autoPlayInterval=b.setInterval(function(){a.next(!0)},a.options.autoPlay)))},swapSpeed:function(a){var b=this;"slideSpeed"===a?b.$easingsliderWrapper.css(b.addCssSpeed(b.options.slideSpeed)):"paginationSpeed"===a?b.$easingsliderWrapper.css(b.addCssSpeed(b.options.paginationSpeed)):"string"!=typeof a&&b.$easingsliderWrapper.css(b.addCssSpeed(a))},addCssSpeed:function(a){return{"-webkit-transition":"all "+a+"ms ease","-moz-transition":"all "+a+"ms ease","-o-transition":"all "+a+"ms ease",transition:"all "+a+"ms ease"}},removeTransition:function(){return{"-webkit-transition":"","-moz-transition":"","-o-transition":"",transition:""}},doTranslate:function(a){return{"-webkit-transform":"translate3d("+a+"px, 0px, 0px)","-moz-transform":"translate3d("+a+"px, 0px, 0px)","-o-transform":"translate3d("+a+"px, 0px, 0px)","-ms-transform":"translate3d("+a+"px, 0px, 0px)",transform:"translate3d("+a+"px, 0px,0px)"}},transition3d:function(a){var b=this;b.$easingsliderWrapper.css(b.doTranslate(a))},css2move:function(a){var b=this;b.$easingsliderWrapper.css({left:a})},css2slide:function(a,b){var c=this;c.isCssFinish=!1,c.$easingsliderWrapper.stop(!0,!0).animate({left:a},{duration:b||c.options.slideSpeed,complete:function(){c.isCssFinish=!0}})},checkBrowser:function(){var a,d,e,f,g=this,h="translate3d(0px, 0px, 0px)",i=c.createElement("div");i.style.cssText=" -moz-transform:"+h+"; -ms-transform:"+h+"; -o-transform:"+h+"; -webkit-transform:"+h+"; transform:"+h,a=/translate3d\(0px, 0px, 0px\)/g,d=i.style.cssText.match(a),e=null!==d&&1===d.length,f="ontouchstart"in b||b.navigator.msMaxTouchPoints,g.browser={support3d:e,isTouch:f}},moveEvents:function(){var a=this;a.options.mouseDrag===!1&&a.options.touchDrag===!1||(a.gestures(),a.disabledEvents())},eventTypes:function(){var a=this,b=["s","e","x"];a.ev_types={},a.options.mouseDrag===!0&&a.options.touchDrag===!0?b=["touchstart.easingslider mousedown.easingslider","touchmove.easingslider mousemove.easingslider","touchend.easingslider touchcancel.easingslider mouseup.easingslider"]:a.options.mouseDrag===!1&&a.options.touchDrag===!0?b=["touchstart.easingslider","touchmove.easingslider","touchend.easingslider touchcancel.easingslider"]:a.options.mouseDrag===!0&&a.options.touchDrag===!1&&(b=["mousedown.easingslider","mousemove.easingslider","mouseup.easingslider"]),a.ev_types.start=b[0],a.ev_types.move=b[1],a.ev_types.end=b[2]},disabledEvents:function(){var b=this;b.$elem.on("dragstart.easingslider",function(a){a.preventDefault()}),b.$elem.on("mousedown.disableTextSelect",function(b){return a(b.target).is("input, textarea, select, option")})},gestures:function(){function d(a){if(void 0!==a.touches)return{x:a.touches[0].pageX,y:a.touches[0].pageY};if(void 0===a.touches){if(void 0!==a.pageX)return{x:a.pageX,y:a.pageY};if(void 0===a.pageX)return{x:a.clientX,y:a.clientY}}}function e(b){"on"===b?(a(c).on(i.ev_types.move,g),a(c).on(i.ev_types.end,h)):"off"===b&&(a(c).off(i.ev_types.move),a(c).off(i.ev_types.end))}function f(c){var f,g=c.originalEvent||c||b.event;if(3===g.which)return!1;if(!(i.itemsAmount<=i.options.items)){if(i.isCssFinish===!1&&!i.options.dragBeforeAnimFinish)return!1;if(i.isCss3Finish===!1&&!i.options.dragBeforeAnimFinish)return!1;i.options.autoPlay!==!1&&b.clearInterval(i.autoPlayInterval),i.browser.isTouch===!0||i.$easingsliderWrapper.hasClass("grabbing")||i.$easingsliderWrapper.addClass("grabbing"),i.newPosX=0,i.newRelativeX=0,a(this).css(i.removeTransition()),f=a(this).position(),j.relativePos=f.left,j.offsetX=d(g).x-f.left,j.offsetY=d(g).y-f.top,e("on"),j.sliding=!1,j.targetElement=g.target||g.srcElement}}function g(e){var f,g,h=e.originalEvent||e||b.event;i.newPosX=d(h).x-j.offsetX,i.newPosY=d(h).y-j.offsetY,i.newRelativeX=i.newPosX-j.relativePos,"function"==typeof i.options.startDragging&&j.dragging!==!0&&0!==i.newRelativeX&&(j.dragging=!0,i.options.startDragging.apply(i,[i.$elem])),(i.newRelativeX>8||i.newRelativeX<-8)&&i.browser.isTouch===!0&&(void 0!==h.preventDefault?h.preventDefault():h.returnValue=!1,j.sliding=!0),(i.newPosY>10||i.newPosY<-10)&&j.sliding===!1&&a(c).off("touchmove.easingslider"),f=function(){return i.newRelativeX/5},g=function(){return i.maximumPixels+i.newRelativeX/5},i.newPosX=Math.max(Math.min(i.newPosX,f()),g()),i.browser.support3d===!0?i.transition3d(i.newPosX):i.css2move(i.newPosX)}function h(c){var d,f,g,h=c.originalEvent||c||b.event;h.target=h.target||h.srcElement,j.dragging=!1,i.browser.isTouch!==!0&&i.$easingsliderWrapper.removeClass("grabbing"),i.newRelativeX<0?i.dragDirection=i.easingslider.dragDirection="left":i.dragDirection=i.easingslider.dragDirection="right",0!==i.newRelativeX&&(d=i.getNewPosition(),i.goTo(d,!1,"drag"),j.targetElement===h.target&&i.browser.isTouch!==!0&&(a(h.target).on("click.disable",function(b){b.stopImmediatePropagation(),b.stopPropagation(),b.preventDefault(),a(b.target).off("click.disable")}),f=a._data(h.target,"events").click,g=f.pop(),f.splice(0,0,g))),e("off")}var i=this,j={offsetX:0,offsetY:0,baseElWidth:0,relativePos:0,position:null,minSwipe:null,maxSwipe:null,sliding:null,dargging:null,targetElement:null};i.isCssFinish=!0,i.$elem.on(i.ev_types.start,".easingslider-wrapper",f)},getNewPosition:function(){var a=this,b=a.closestItem();return b>a.maximumItem?(a.currentItem=a.maximumItem,b=a.maximumItem):a.newPosX>=0&&(b=0,a.currentItem=0),b},closestItem:function(){var b=this,c=b.options.scrollPerPage===!0?b.pagesInArray:b.positionsInArray,d=b.newPosX,e=null;return a.each(c,function(f,g){d-b.itemWidth/20>c[f+1]&&d-b.itemWidth/20<g&&"left"===b.moveDirection()?(e=g,b.options.scrollPerPage===!0?b.currentItem=a.inArray(e,b.positionsInArray):b.currentItem=f):d+b.itemWidth/20<g&&d+b.itemWidth/20>(c[f+1]||c[f]-b.itemWidth)&&"right"===b.moveDirection()&&(b.options.scrollPerPage===!0?(e=c[f+1]||c[c.length-1],b.currentItem=a.inArray(e,b.positionsInArray)):(e=c[f+1],b.currentItem=f+1))}),b.currentItem},moveDirection:function(){var a,b=this;return b.newRelativeX<0?(a="right",b.playDirection="next"):(a="left",b.playDirection="prev"),a},customEvents:function(){var a=this;a.$elem.on("easingslider.next",function(){a.next()}),a.$elem.on("easingslider.prev",function(){a.prev()}),a.$elem.on("easingslider.play",function(b,c){a.options.autoPlay=c,a.play(),a.hoverStatus="play"}),a.$elem.on("easingslider.stop",function(){a.stop(),a.hoverStatus="stop"}),a.$elem.on("easingslider.goTo",function(b,c){a.goTo(c)}),a.$elem.on("easingslider.jumpTo",function(b,c){a.jumpTo(c)})},stopOnHover:function(){var a=this;a.options.stopOnHover===!0&&a.browser.isTouch!==!0&&a.options.autoPlay!==!1&&(a.$elem.on("mouseover",function(){a.stop()}),a.$elem.on("mouseout",function(){"stop"!==a.hoverStatus&&a.play()}))},lazyLoad:function(){var b,c,d,e,f,g=this;if(g.options.lazyLoad===!1)return!1;for(b=0;b<g.itemsAmount;b+=1)c=a(g.$easingsliderItems[b]),"loaded"!==c.data("easingslider-loaded")&&(d=c.data("easingslider-item"),e=c.find(".easingslider-lazy"),"string"==typeof e.data("src")?(void 0===c.data("easingslider-loaded")&&(e.hide(),c.addClass("loading").data("easingslider-loaded","checked")),f=g.options.lazyFollow===!0?d>=g.currentItem:!0,f&&d<g.currentItem+g.options.items&&e.length&&g.lazyPreload(c,e)):c.data("easingslider-loaded","loaded"))},lazyPreload:function(a,c){function d(){a.data("easingslider-loaded","loaded").removeClass("loading"),c.removeAttr("data-src"),"fade"===g.options.lazyEffect?c.fadeIn(400):c.show(),"function"==typeof g.options.afterLazyLoad&&g.options.afterLazyLoad.apply(this,[g.$elem])}function e(){h+=1,g.completeImg(c.get(0))||f===!0?d():100>=h?b.setTimeout(e,100):d()}var f,g=this,h=0;"DIV"===c.prop("tagName")?(c.css("background-image","url("+c.data("src")+")"),f=!0):c[0].src=c.data("src"),e()},autoHeight:function(){function c(){var c=a(f.$easingsliderItems[f.currentItem]).height();f.wrapperOuter.css("height",c+"px"),f.wrapperOuter.hasClass("autoHeight")||b.setTimeout(function(){f.wrapperOuter.addClass("autoHeight")},0)}function d(){e+=1,f.completeImg(g.get(0))?c():100>=e?b.setTimeout(d,100):f.wrapperOuter.css("height","")}var e,f=this,g=a(f.$easingsliderItems[f.currentItem]).find("img");void 0!==g.get(0)?(e=0,d()):c()},completeImg:function(a){var b;return a.complete?(b=typeof a.naturalWidth,"undefined"===b||0!==a.naturalWidth):!1},onVisibleItems:function(){var b,c=this;for(c.options.addClassActive===!0&&c.$easingsliderItems.removeClass("active"),c.visibleItems=[],b=c.currentItem;b<c.currentItem+c.options.items;b+=1)c.visibleItems.push(b),c.options.addClassActive===!0&&a(c.$easingsliderItems[b]).addClass("active");c.easingslider.visibleItems=c.visibleItems},transitionTypes:function(a){var b=this;b.outClass="easingslider-"+a+"-out",b.inClass="easingslider-"+a+"-in"},singleItemTransition:function(){function a(a){return{position:"relative",left:a+"px"}}var b=this,c=b.outClass,d=b.inClass,e=b.$easingsliderItems.eq(b.currentItem),f=b.$easingsliderItems.eq(b.prevItem),g=Math.abs(b.positionsInArray[b.currentItem])+b.positionsInArray[b.prevItem],h=Math.abs(b.positionsInArray[b.currentItem])+b.itemWidth/2,i="webkitAnimationEnd oAnimationEnd MSAnimationEnd animationend";b.isTransition=!0,b.$easingsliderWrapper.addClass("easingslider-origin").css({"-webkit-transform-origin":h+"px","-moz-perspective-origin":h+"px","perspective-origin":h+"px"}),f.css(a(g,10)).addClass(c).on(i,function(){b.endPrev=!0,f.off(i),b.clearTransStyle(f,c)}),e.addClass(d).on(i,function(){b.endCurrent=!0,e.off(i),b.clearTransStyle(e,d)})},clearTransStyle:function(a,b){var c=this;a.css({position:"",left:""}).removeClass(b),c.endPrev&&c.endCurrent&&(c.$easingsliderWrapper.removeClass("easingslider-origin"),c.endPrev=!1,c.endCurrent=!1,c.isTransition=!1)},easingsliderStatus:function(){var a=this;a.easingslider={userOptions:a.userOptions,baseElement:a.$elem,userItems:a.$userItems,easingsliderItems:a.$easingsliderItems,currentItem:a.currentItem,prevItem:a.prevItem,visibleItems:a.visibleItems,isTouch:a.browser.isTouch,browser:a.browser,dragDirection:a.dragDirection}},clearEvents:function(){var d=this;d.$elem.off(".easingslider easingslider mousedown.disableTextSelect"),a(c).off(".easingslider easingslider"),a(b).off("resize",d.resizer)},unWrap:function(){var a=this;0!==a.$elem.children().length&&(a.$easingsliderWrapper.unwrap(),a.$userItems.unwrap().unwrap(),a.easingsliderControls&&a.easingsliderControls.remove()),a.clearEvents(),a.$elem.attr("style",a.$elem.data("easingslider-originalStyles")||"").attr("class",a.$elem.data("easingslider-originalClasses"))},destroy:function(){var a=this;a.stop(),b.clearInterval(a.checkVisible),a.unWrap(),a.$elem.removeData()},reinit:function(b){var c=this,d=a.extend({},c.userOptions,b);c.unWrap(),c.init(d,c.$elem)},addItem:function(a,b){var c,d=this;return a?0===d.$elem.children().length?(d.$elem.append(a),d.setVars(),!1):(d.unWrap(),c=void 0===b||-1===b?-1:b,c>=d.$userItems.length||-1===c?d.$userItems.eq(-1).after(a):d.$userItems.eq(c).before(a),void d.setVars()):!1},removeItem:function(a){var b,c=this;return 0===c.$elem.children().length?!1:(b=void 0===a||-1===a?-1:a,c.unWrap(),c.$userItems.eq(b).remove(),void c.setVars())}};a.fn.easingSlider=function(b){return this.each(function(){if(a(this).data("easingslider-init")===!0)return!1;a(this).data("easingslider-init",!0);var c=Object.create(d);c.init(b,this),a.data(this,"easingSlider",c)})},a.fn.easingSlider.options={items:5,itemsCustom:!1,itemsDesktop:[1199,4],itemsDesktopSmall:[979,3],itemsTablet:[768,2],itemsTabletSmall:!1,itemsMobile:[479,1],singleItem:!1,itemsScaleUp:!1,slideSpeed:200,paginationSpeed:800,rewindSpeed:1e3,autoPlay:!1,stopOnHover:!1,navigation:!1,navigationText:["prev","next"],rewindNav:!0,scrollPerPage:!1,pagination:!0,paginationNumbers:!1,responsive:!0,responsiveRefreshRate:200,responsiveBaseWidth:b,baseClass:"easingslider",theme:"easingslider-theme",lazyLoad:!1,lazyFollow:!0,lazyEffect:"fade",autoHeight:!1,jsonPath:!1,jsonSuccess:!1,dragBeforeAnimFinish:!0,mouseDrag:!0,touchDrag:!0,addClassActive:!1,transitionStyle:!1,beforeUpdate:!1,afterUpdate:!1,beforeInit:!1,afterInit:!1,beforeMove:!1,afterMove:!1,afterAction:!1,startDragging:!1,afterLazyLoad:!1}}(jQuery,window,document),function(a){a.EasingSlider=function(b){var c=this;c.el=b,c.$el=a(c.el),c.$wrapper=c.$el.find(".easingslider-wrapper"),c.$slides=c.$el.find(".easingslider-slide"),c.$images=c.$el.find(".easingslider-image"),c.options=window["EasingSlider"+c.$el.attr("data-id")],c._clickEvent="ontouchstart"in document.documentElement?"touchstart":"click",c.$el.data("easingslider",c),c.initSlider=function(){c.$el.easingSlider(a.extend(c.options,{afterInit:function(){c._maybeResize()},afterUpdate:function(){c._maybeResize()},afterAction:function(){c.$el.trigger("changeSlide",this.currentItem)}}))},c._maybeResize=function(){return c.$el.hasClass("easingslider-aspect-ratio")&&c.doResize(),c},c.doResize=function(){var a=c.$el.outerWidth(),b=c.$el.find(".easingslider-wrapper-outer");if(a<=c.options.width){var d=Math.floor(a/c.options.width*c.options.height);c.$el.css({height:d+"px"}),c.$wrapper.css({height:d+"px"}),c.$images.css({"max-height":d+"px"})}else c.$el.css({height:c.options.height+"px"}),c.$wrapper.css({height:c.options.height+"px"}),c.$images.css({"max-height":c.options.height+"px"});return b.css({width:Math.floor(b.outerWidth())+"px"}),c},c.initSlider()},a.fn.EasingSlider=function(){return this.each(function(){new a.EasingSlider(this)})},a(document).ready(function(){a(".easingslider").EasingSlider()})}(jQuery);
backbone/slide.php DELETED
@@ -1,49 +0,0 @@
1
- <script type="text/html" id="tmpl-easingslider-slide">
2
- <div class="attachment-preview {{ data.model.type }}-slide js--select-attachment">
3
- <div class="toolbar">
4
- <i class="dashicons dashicons-edit edit"></i>
5
- <i class="dashicons dashicons-no-alt remove"></i>
6
- </div>
7
-
8
- <div class="thumbnail">
9
- <# if ( 'image' === data.model.type ) { #>
10
- <div class="centered">
11
- <# if ( data.attachment && data.attachment.sizes ) { #>
12
- <# var image = data.attachment.sizes.thumbnail || data.attachment.sizes.medium || data.attachment.sizes.large || data.attachment.sizes.full #>
13
- <img src="{{ image.url }}" draggable="true" alt="" />
14
- <# } else { #>
15
- <img src="{{ data.model.url }}" draggable="true" alt="" />
16
- <# } #>
17
- </div>
18
- <# } else if ( data.attachment ) { #>
19
- <div class="centered">
20
- <# if ( data.attachment.image && data.attachment.image.src && data.attachment.image.src !== data.attachment.icon ) { #>
21
- <img src="{{ data.attachment.image.src }}" class="thumbnail" draggable="true" />
22
- <# } else { #>
23
- <img src="{{ data.attachment.icon }}" class="icon" draggable="true" />
24
- <# } #>
25
- </div>
26
- <div class="filename">
27
- <div>{{ data.attachment.filename }}</div>
28
- </div>
29
- <# } #>
30
-
31
- <?php
32
- /**
33
- * This is for our extensions and their custom thumbnails
34
- */
35
- do_action( 'easingslider_print_thumbnail' );
36
- ?>
37
- </div>
38
- </div>
39
-
40
- <a class="check" href="#" title="<?php esc_attr_e('Deselect'); ?>" tabindex="-1"><div class="media-modal-icon"></div></a>
41
-
42
- <?php
43
- /**
44
- * This hidden attribute is kept in-sync with our model data.
45
- * Everytime a change is made to the model, it's data is dumped here so we can fetch it with PHP.
46
- */
47
- ?>
48
- <input type="hidden" name="slides[]" value="{{ JSON.stringify(data.model) }}" />
49
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bower.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Easing Slider",
3
+ "version": "3.0.0",
4
+ "homepage": "https://github.com/easingslider/easing-slider",
5
+ "authors": [
6
+ "MatthewRuddy <info@matthewruddy.com>"
7
+ ],
8
+ "private": true,
9
+ "ignore": [
10
+ "**/.*",
11
+ "node_modules",
12
+ "bower_components",
13
+ "test",
14
+ "tests"
15
+ ],
16
+ "dependencies": {
17
+ "owlcarousel": "~1.3.2"
18
+ }
19
+ }
css/customizer.css DELETED
@@ -1,12 +0,0 @@
1
- #customize-container {
2
- display: block;
3
- }
4
-
5
- #customize-container #customize-controls {
6
- z-index: 9999;
7
- }
8
-
9
- #customize-container #customize-preview {
10
- min-width: 300px;
11
- margin: 45px;
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
css/customizer.min.css DELETED
@@ -1 +0,0 @@
1
- #customize-container{display:block}#customize-container #customize-controls{z-index:9999}#customize-container #customize-preview{min-width:300px;margin:45px}
 
css/easingslider.css DELETED
@@ -1,707 +0,0 @@
1
- /* Slider
2
- -------------------------------------------------------------- */
3
- .easingslider,
4
- .easingslider-viewport,
5
- .easingslider-slide,
6
- .easingslider-link,
7
- .easingslider-image {
8
- line-height: 0 !important;
9
- outline: none !important;
10
- padding: 0 !important;
11
- margin: 0 !important;
12
- }
13
-
14
- .easingslider-viewport,
15
- .easingslider-slide,
16
- .easingslider-link,
17
- .easingslider-image {
18
- clear: none !important;
19
- border: 0 !important;
20
- }
21
-
22
- .easingslider {
23
- position: relative !important;
24
- z-index: 0;
25
- }
26
-
27
- .easingslider.has-loaded .easingslider-arrows,
28
- .easingslider.has-loaded .easingslider-pagination {
29
- opacity: 1;
30
- }
31
-
32
- .easingslider-viewport {
33
- position: relative !important;
34
- }
35
-
36
- .easingslider-preload {
37
- background-image: url(../images/loading.gif);
38
- background-repeat: no-repeat;
39
- background-position: center center;
40
- background-color: #fff;
41
- width: 100% !important;
42
- height: 100% !important;
43
- position: absolute !important;
44
- top: 0 !important;
45
- left: 0 !important;
46
- z-index: 50 !important;
47
- }
48
-
49
- .easingslider-slide {
50
- position: absolute !important;
51
- top: 0;
52
- left: 0;
53
- bottom: 0;
54
- right: 0;
55
- background-color: #fff;
56
- overflow: hidden;
57
- }
58
-
59
- .easingslider-slide.active {
60
- z-index: 10 !important;
61
- }
62
-
63
- .easingslider-slide.next-out,
64
- .easingslider-slide.prev-out {
65
- z-index: 20 !important;
66
- }
67
-
68
- .easingslider-slide.next-in,
69
- .easingslider-slide.prev-in {
70
- z-index: 30 !important;
71
- }
72
-
73
- .easingslider-background-slide {
74
- -webkit-background-size: cover;
75
- -moz-background-size: cover;
76
- background-size: cover;
77
- background-repeat: no-repeat;
78
- background-position: center center;
79
- }
80
-
81
- .easingslider-link {
82
- position: relative !important;
83
- display: block !important;
84
- height: 100% !important;
85
- }
86
-
87
- .easingslider-image {
88
- max-width: 100% !important;
89
- max-height: none !important;
90
- width: auto !important;
91
- height: auto !important;
92
- margin-left: auto !important;
93
- margin-right: auto !important;
94
- display: block;
95
- position: absolute;
96
- top: 0;
97
- left: 0;
98
- bottom: 0;
99
- right: 0;
100
- }
101
-
102
- .easingslider .easingslider-arrows.has-hover,
103
- .easingslider .easingslider-pagination.has-hover {
104
- opacity: 0;
105
- }
106
-
107
- .easingslider:hover .easingslider-arrows.has-hover,
108
- .easingslider:hover .easingslider-pagination.has-hover {
109
- opacity: 1;
110
- }
111
-
112
- /* Play
113
- -------------------------------------------------------------- */
114
- .easingslider-play {
115
- position: absolute;
116
- top: 0;
117
- right: 0;
118
- bottom: 0;
119
- left: 0;
120
- background-image: url(../images/nav-play.png);
121
- background-repeat: no-repeat;
122
- background-position: center center;
123
- background-color: transparent;
124
- z-index: 50;
125
- opacity: 0;
126
- -webkit-transition: opacity 0.1s ease-in;
127
- -moz-transition: opacity 0.1s ease-in;
128
- -ms-transition: opacity 0.1s ease-in;
129
- -o-transition: opacity 0.1s ease-in;
130
- transition: opacity 0.1s ease-in;
131
- }
132
-
133
- .easingslider-slide.active .easingslider-play {
134
- opacity: 0.5;
135
- }
136
-
137
- .easingslider-slide.active .easingslider-play:hover {
138
- opacity: 1;
139
- }
140
-
141
- /* Arrows
142
- -------------------------------------------------------------- */
143
- .easingslider-arrows {
144
- position: absolute;
145
- top: 50%;
146
- width: 30px;
147
- height: 30px;
148
- margin-top: -15px;
149
- background-repeat: no-repeat;
150
- z-index: 40;
151
- cursor: pointer;
152
- opacity: 0;
153
- -webkit-transition: opacity 0.3s ease, -webkit-transform 0.1s ease-in;
154
- -moz-transition: opacity 0.3s ease, -moz-transform 0.1s ease-in;
155
- -ms-transition: opacity 0.3s ease, -ms-transform 0.1s ease-in;
156
- -o-transition: opacity 0.3s ease, -o-transform 0.1s ease-in;
157
- transition: opacity 0.3s ease, transform 0.1s ease-in;
158
- }
159
-
160
- .easingslider-arrows.easingslider-next {
161
- background-image: url(../images/nav-arrow-next.png);
162
- background-position: top right;
163
- }
164
-
165
- .easingslider-arrows.easingslider-prev {
166
- background-image: url(../images/nav-arrow-prev.png);
167
- background-position: top left;
168
- }
169
-
170
- .easingslider-arrows.easingslider-next.inside {
171
- right: 10px;
172
- }
173
-
174
- .easingslider-arrows.easingslider-next.outside {
175
- right: -40px;
176
- padding-left: 20px;
177
- }
178
-
179
- .easingslider-arrows.easingslider-prev.inside {
180
- left: 10px;
181
- }
182
-
183
- .easingslider-arrows.easingslider-prev.outside {
184
- left: -40px;
185
- padding-right: 20px;
186
- }
187
-
188
- .easingslider .easingslider-prev.has-hover {
189
- -webkit-transform: translate3d(-10px, 0, 0);
190
- -moz-transform: translate3d(-10px, 0, 0);
191
- -ms-transform: translate3d(-10px, 0, 0);
192
- -o-transform: translate3d(-10px, 0, 0);
193
- transform: translate3d(-10px, 0, 0);
194
- }
195
-
196
- .easingslider .easingslider-next.has-hover {
197
- -webkit-transform: translate3d(10px, 0, 0);
198
- -moz-transform: translate3d(10px, 0, 0);
199
- -ms-transform: translate3d(10px, 0, 0);
200
- -o-transform: translate3d(10px, 0, 0);
201
- transform: translate3d(10px, 0, 0);
202
- }
203
-
204
- .easingslider:hover .easingslider-prev.has-hover,
205
- .easingslider:hover .easingslider-next.has-hover {
206
- -webkit-transform: translate3d(0, 0, 0);
207
- -moz-transform: translate3d(0, 0, 0);
208
- -ms-transform: translate3d(0, 0, 0);
209
- -o-transform: translate3d(0, 0, 0);
210
- transform: translate3d(0, 0, 0);
211
- }
212
-
213
- /* Pagination
214
- -------------------------------------------------------------- */
215
- .easingslider-pagination {
216
- position: absolute;
217
- z-index: 40;
218
- opacity: 0;
219
- -webkit-transition: opacity 0.3s ease;
220
- -moz-transition: opacity 0.3s ease;
221
- -ms-transition: opacity 0.3s ease;
222
- -o-transition: opacity 0.3s ease;
223
- transition: opacity 0.3s ease;
224
- }
225
-
226
- .easingslider-pagination.inside.bottom-left {
227
- bottom: 10px;
228
- left: 10px;
229
- }
230
-
231
- .easingslider-pagination.inside.bottom-right {
232
- bottom: 10px;
233
- right: 10px;
234
- }
235
-
236
- .easingslider-pagination.inside.bottom-center {
237
- bottom: 10px;
238
- left: 0;
239
- width: 100%;
240
- text-align: center;
241
- }
242
-
243
- .easingslider-pagination.inside.top-left {
244
- top: 10px;
245
- left: 10px;
246
- }
247
-
248
- .easingslider-pagination.inside.top-right {
249
- top: 10px;
250
- right: 10px;
251
- }
252
-
253
- .easingslider-pagination.inside.top-center {
254
- top: 10px;
255
- left: 0;
256
- width: 100%;
257
- text-align: center;
258
- }
259
-
260
- .easingslider-pagination.outside.bottom-left {
261
- bottom: -25px;
262
- left: 0;
263
- padding-top: 20px;
264
- }
265
-
266
- .easingslider-pagination.outside.bottom-right {
267
- bottom: -25px;
268
- right: 0;
269
- padding-top: 20px;
270
- }
271
-
272
- .easingslider-pagination.outside.bottom-center {
273
- bottom: -25px;
274
- left: 0;
275
- width: 100%;
276
- text-align: center;
277
- padding-top: 20px;
278
- }
279
-
280
- .easingslider-pagination.outside.top-left {
281
- top: -25px;
282
- left: 0;
283
- padding-bottom: 20px;
284
- }
285
-
286
- .easingslider-pagination.outside.top-right {
287
- top: -25px;
288
- right: 0;
289
- padding-bottom: 20px;
290
- }
291
-
292
- .easingslider-pagination.outside.top-center {
293
- top: -25px;
294
- left: 0;
295
- width: 100%;
296
- text-align: center;
297
- padding-bottom: 20px;
298
- }
299
-
300
- .easingslider-pagination .easingslider-icon {
301
- width: 15px;
302
- height: 15px;
303
- margin: 0;
304
- padding: 0;
305
- background-image: url(../images/nav-icon-inactive.png);
306
- background-repeat: no-repeat;
307
- background-position: 0 0;
308
- display: inline-block;
309
- *display: inline; /** IE7 hack */
310
- zoom: 1; /** IE7 hack */
311
- z-index: 40;
312
- cursor: pointer;
313
- }
314
-
315
- .easingslider-pagination .easingslider-icon:last-child {
316
- margin-right: 0;
317
- }
318
-
319
- .easingslider-pagination .easingslider-icon.active {
320
- background-image: url(../images/nav-icon-active.png);
321
- }
322
-
323
- .easingslider .easingslider-pagination.has-hover {
324
- opacity: 0;
325
- }
326
-
327
- .easingslider:hover .easingslider-pagination.has-hover {
328
- opacity: 1;
329
- }
330
-
331
- /* "Fade" transition
332
- -------------------------------------------------------------- */
333
- .easingslider.use-fade .easingslider-slide.next-in,
334
- .easingslider.use-fade .easingslider-slide.prev-in {
335
- -webkit-animation: fadeIn 0.3s ease;
336
- -moz-animation: fadeIn 0.3s ease;
337
- -ms-animation: fadeIn 0.3s ease;
338
- -o-animation: fadeIn 0.3s ease;
339
- animation: fadeIn 0.3s ease;
340
- }
341
-
342
- ._easingslider.use-fade .easingslider-slide.next-out,
343
- ._easingslider.use-fade .easingslider-slide.prev-out {
344
- -webkit-animation: fadeOut 0.3s ease;
345
- -moz-animation: fadeOut 0.3s ease;
346
- -ms-animation: fadeOut 0.3s ease;
347
- -o-animation: fadeOut 0.3s ease;
348
- animation: fadeOut 0.3s ease;
349
- }
350
-
351
- @-webkit-keyframes fadeIn {
352
- 0% {
353
- opacity: 0;
354
- }
355
- 100% {
356
- opacity: 1;
357
- }
358
- }
359
- @-moz-keyframes fadeIn {
360
- 0% {
361
- opacity: 0;
362
- }
363
- 100% {
364
- opacity: 1;
365
- }
366
- }
367
- @-ms-keyframes fadeIn {
368
- 0% {
369
- opacity: 0;
370
- }
371
- 100% {
372
- opacity: 1;
373
- }
374
- }
375
- @-o-keyframes fadeIn {
376
- 0% {
377
- opacity: 0;
378
- }
379
- 100% {
380
- opacity: 1;
381
- }
382
- }
383
- @keyframes fadeIn {
384
- 0% {
385
- opacity: 0;
386
- }
387
- 100% {
388
- opacity: 1;
389
- }
390
- }
391
-
392
- @-webkit-keyframes fadeOut {
393
- 0% {
394
- opacity: 1;
395
- }
396
- 100% {
397
- opacity: 0;
398
- }
399
- }
400
- @-moz-keyframes fadeOut {
401
- 0% {
402
- opacity: 1;
403
- }
404
- 100% {
405
- opacity: 0;
406
- }
407
- }
408
- @-ms-keyframes fadeOut {
409
- 0% {
410
- opacity: 1;
411
- }
412
- 100% {
413
- opacity: 0;
414
- }
415
- }
416
- @-o-keyframes fadeOut {
417
- 0% {
418
- opacity: 1;
419
- }
420
- 100% {
421
- opacity: 0;
422
- }
423
- }
424
- @keyframes fadeOut {
425
- 0% {
426
- opacity: 1;
427
- }
428
- 100% {
429
- opacity: 0;
430
- }
431
- }
432
-
433
- /* "Slide" transition
434
- -------------------------------------------------------------- */
435
- .easingslider.use-slide .easingslider-viewport {
436
- overflow: hidden;
437
- }
438
-
439
- .easingslider.use-slide .easingslider-slide.next-in {
440
- -webkit-animation: slideNextIn 0.3s ease;
441
- -moz-animation: slideNextIn 0.3s ease;
442
- -ms-animation: slideNextIn 0.3s ease;
443
- -o-animation: slideNextIn 0.3s ease;
444
- animation: slideNextIn 0.3s ease;
445
- }
446
-
447
- .easingslider.use-slide .easingslider-slide.next-out {
448
- -webkit-animation: slideNextOut 0.3s ease;
449
- -moz-animation: slideNextOut 0.3s ease;
450
- -ms-animation: slideNextOut 0.3s ease;
451
- -o-animation: slideNextOut 0.3s ease;
452
- animation: slideNextOut 0.3s ease;
453
- }
454
-
455
- .easingslider.use-slide .easingslider-slide.prev-out {
456
- -webkit-animation: slidePrevOut 0.3s ease;
457
- -moz-animation: slidePrevOut 0.3s ease;
458
- -ms-animation: slidePrevOut 0.3s ease;
459
- -o-animation: slidePrevOut 0.3s ease;
460
- animation: slidePrevOut 0.3s ease;
461
- }
462
-
463
- .easingslider.use-slide .easingslider-slide.prev-in {
464
- -webkit-animation: slidePrevIn 0.3s ease;
465
- -moz-animation: slidePrevIn 0.3s ease;
466
- -ms-animation: slidePrevIn 0.3s ease;
467
- -o-animation: slidePrevIn 0.3s ease;
468
- animation: slidePrevIn 0.3s ease;
469
- }
470
-
471
- @-webkit-keyframes slideNextIn {
472
- 0% {
473
- -webkit-transform: translate3d(100%, 0, 0);
474
- transform: translate3d(100%, 0, 0);
475
- }
476
- 100% {
477
- -webkit-transform: none;
478
- transform: none;
479
- }
480
- }
481
- @-moz-keyframes slideNextIn {
482
- 0% {
483
- -moz-transform: translate3d(100%, 0, 0);
484
- transform: translate3d(100%, 0, 0);
485
- }
486
- 100% {
487
- -moz-transform: none;
488
- transform: none;
489
- }
490
- }
491
- @-ms-keyframes slideNextIn {
492
- 0% {
493
- -ms-transform: translate3d(100%, 0, 0);
494
- transform: translate3d(100%, 0, 0);
495
- }
496
- 100% {
497
- -ms-transform: none;
498
- transform: none;
499
- }
500
- }
501
- @-o-keyframes slideNextIn {
502
- 0% {
503
- -o-transform: translate3d(100%, 0, 0);
504
- transform: translate3d(100%, 0, 0);
505
- }
506
- 100% {
507
- -o-transform: none;
508
- transform: none;
509
- }
510
- }
511
- @keyframes slideNextIn {
512
- 0% {
513
- transform: translate3d(100%, 0, 0);
514
- }
515
- 100% {
516
- transform: none;
517
- }
518
- }
519
-
520
- @-webkit-keyframes slideNextOut {
521
- 0% {
522
- -webkit-transform: none;
523
- transform: none;
524
- }
525
- 100% {
526
- -webkit-transform: translate3d(100%, 0, 0);
527
- transform: translate3d(100%, 0, 0);
528
- }
529
- }
530
- @-moz-keyframes slideNextOut {
531
- 0% {
532
- -moz-transform: none;
533
- transform: none;
534
- }
535
- 100% {
536
- -moz-transform: translate3d(100%, 0, 0);
537
- transform: translate3d(100%, 0, 0);
538
- }
539
- }
540
- @-ms-keyframes slideNextOut {
541
- 0% {
542
- -ms-transform: none;
543
- transform: none;
544
- }
545
- 100% {
546
- -ms-transform: translate3d(100%, 0, 0);
547
- transform: translate3d(100%, 0, 0);
548
- }
549
- }
550
- @-o-keyframes slideNextOut {
551
- 0% {
552
- -o-transform: none;
553
- transform: none;
554
- }
555
- 100% {
556
- -o-transform: translate3d(100%, 0, 0);
557
- transform: translate3d(100%, 0, 0);
558
- }
559
- }
560
- @keyframes slideNextOut {
561
- 0% {
562
- transform: none;
563
- }
564
- 100% {
565
- transform: translate3d(100%, 0, 0);
566
- }
567
- }
568
-
569
- @-webkit-keyframes slidePrevOut {
570
- 0% {
571
- -webkit-transform: none;
572
- transform: none;
573
- }
574
- 100% {
575
- -webkit-transform: translate3d(-100%, 0, 0);
576
- transform: translate3d(-100%, 0, 0);
577
- }
578
- }
579
- @-moz-keyframes slidePrevOut {
580
- 0% {
581
- -moz-transform: none;
582
- transform: none;
583
- }
584
- 100% {
585
- -moz-transform: translate3d(-100%, 0, 0);
586
- transform: translate3d(-100%, 0, 0);
587
- }
588
- }
589
- @-ms-keyframes slidePrevOut {
590
- 0% {
591
- -ms-transform: none;
592
- transform: none;
593
- }
594
- 100% {
595
- -ms-transform: translate3d(-100%, 0, 0);
596
- transform: translate3d(-100%, 0, 0);
597
- }
598
- }
599
- @-o-keyframes slidePrevOut {
600
- 0% {
601
- -o-transform: none;
602
- transform: none;
603
- }
604
- 100% {
605
- -o-transform: translate3d(-100%, 0, 0);
606
- transform: translate3d(-100%, 0, 0);
607
- }
608
- }
609
- @keyframes slidePrevOut {
610
- 0% {
611
- transform: none;
612
- }
613
- 100% {
614
- transform: translate3d(-100%, 0, 0);
615
- }
616
- }
617
-
618
- @-webkit-keyframes slidePrevIn {
619
- 0% {
620
- -webkit-transform: translate3d(-100%, 0, 0);
621
- transform: translate3d(-100%, 0, 0);
622
- }
623
- 100% {
624
- -webkit-transform: none;
625
- transform: none;
626
- }
627
- }
628
- @-moz-keyframes slidePrevIn {
629
- 0% {
630
- -moz-transform: translate3d(-100%, 0, 0);
631
- transform: translate3d(-100%, 0, 0);
632
- }
633
- 100% {
634
- -moz-transform: none;
635
- transform: none;
636
- }
637
- }
638
- @-ms-keyframes slidePrevIn {
639
- 0% {
640
- -ms-transform: translate3d(-100%, 0, 0);
641
- transform: translate3d(-100%, 0, 0);
642
- }
643
- 100% {
644
- -ms-transform: none;
645
- transform: none;
646
- }
647
- }
648
- @-o-keyframes slidePrevIn {
649
- 0% {
650
- -o-transform: translate3d(-100%, 0, 0);
651
- transform: translate3d(-100%, 0, 0);
652
- }
653
- 100% {
654
- -o-transform: none;
655
- transform: none;
656
- }
657
- }
658
- @keyframes slidePrevIn {
659
- 0% {
660
- transform: translate3d(-100%, 0, 0);
661
- }
662
- 100% {
663
- transform: none;
664
- }
665
- }
666
-
667
- /* Retina
668
- -------------------------------------------------------------- */
669
- @media
670
- only screen and (-webkit-min-device-pixel-ratio: 2),
671
- only screen and ( min--moz-device-pixel-ratio: 2),
672
- only screen and ( -o-min-device-pixel-ratio: 2/1),
673
- only screen and ( min-device-pixel-ratio: 2),
674
- only screen and ( min-resolution: 192dpi),
675
- only screen and ( min-resolution: 2dppx) {
676
-
677
- .easingslider-preload {
678
- background-image: url(../images/loading@2x.gif);
679
- background-size: 24px 24px;
680
- }
681
-
682
- .easingslider-play {
683
- background-image: url(../images/nav-play@2x.png);
684
- background-size: 40px 40px;
685
- }
686
-
687
- .easingslider-arrows.easingslider-next {
688
- background-image: url(../images/nav-arrow-next@2x.png);
689
- background-size: 30px 30px;
690
- }
691
-
692
- .easingslider-arrows.easingslider-prev {
693
- background-image: url(../images/nav-arrow-prev@2x.png);
694
- background-size: 30px 30px;
695
- }
696
-
697
- .easingslider .easingslider-icon {
698
- background-image: url(../images/nav-icon-inactive@2x.png);
699
- background-size: 14px 14px;
700
- }
701
-
702
- .easingslider .easingslider-icon.active {
703
- background-image: url(../images/nav-icon-active@2x.png);
704
- background-size: 14px 14px;
705
- }
706
-
707
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/easingslider.min.css DELETED
@@ -1 +0,0 @@
1
- .easingslider,.easingslider-image,.easingslider-link,.easingslider-slide,.easingslider-viewport{line-height:0!important;outline:0!important;padding:0!important;margin:0!important}.easingslider-image,.easingslider-link,.easingslider-slide,.easingslider-viewport{clear:none!important;border:0!important}.easingslider{position:relative!important;z-index:0}.easingslider.has-loaded .easingslider-arrows,.easingslider.has-loaded .easingslider-pagination{opacity:1}.easingslider-viewport{position:relative!important}.easingslider-preload{background-image:url(../images/loading.gif);background-repeat:no-repeat;background-position:center center;background-color:#fff;width:100%!important;height:100%!important;position:absolute!important;top:0!important;left:0!important;z-index:50!important}.easingslider-slide{position:absolute!important;top:0;left:0;bottom:0;right:0;background-color:#fff;overflow:hidden}.easingslider-slide.active{z-index:10!important}.easingslider-slide.next-out,.easingslider-slide.prev-out{z-index:20!important}.easingslider-slide.next-in,.easingslider-slide.prev-in{z-index:30!important}.easingslider-background-slide{-webkit-background-size:cover;-moz-background-size:cover;background-size:cover;background-repeat:no-repeat;background-position:center center}.easingslider-link{position:relative!important;display:block!important;height:100%!important}.easingslider-image{max-width:100%!important;max-height:none!important;width:auto!important;height:auto!important;margin-left:auto!important;margin-right:auto!important;display:block;position:absolute;top:0;left:0;bottom:0;right:0}.easingslider .easingslider-arrows.has-hover,.easingslider .easingslider-pagination.has-hover{opacity:0}.easingslider:hover .easingslider-arrows.has-hover,.easingslider:hover .easingslider-pagination.has-hover{opacity:1}.easingslider-play{position:absolute;top:0;right:0;bottom:0;left:0;background-image:url(../images/nav-play.png);background-repeat:no-repeat;background-position:center center;background-color:transparent;z-index:50;opacity:0;-webkit-transition:opacity .1s ease-in;-moz-transition:opacity .1s ease-in;-ms-transition:opacity .1s ease-in;-o-transition:opacity .1s ease-in;transition:opacity .1s ease-in}.easingslider-slide.active .easingslider-play{opacity:.5}.easingslider-slide.active .easingslider-play:hover{opacity:1}.easingslider-arrows{position:absolute;top:50%;width:30px;height:30px;margin-top:-15px;background-repeat:no-repeat;z-index:40;cursor:pointer;opacity:0;-webkit-transition:opacity .3s ease,-webkit-transform .1s ease-in;-moz-transition:opacity .3s ease,-moz-transform .1s ease-in;-ms-transition:opacity .3s ease,-ms-transform .1s ease-in;-o-transition:opacity .3s ease,-o-transform .1s ease-in;transition:opacity .3s ease,transform .1s ease-in}.easingslider-arrows.easingslider-next{background-image:url(../images/nav-arrow-next.png);background-position:top right}.easingslider-arrows.easingslider-prev{background-image:url(../images/nav-arrow-prev.png);background-position:top left}.easingslider-arrows.easingslider-next.inside{right:10px}.easingslider-arrows.easingslider-next.outside{right:-40px;padding-left:20px}.easingslider-arrows.easingslider-prev.inside{left:10px}.easingslider-arrows.easingslider-prev.outside{left:-40px;padding-right:20px}.easingslider .easingslider-prev.has-hover{-webkit-transform:translate3d(-10px,0,0);-moz-transform:translate3d(-10px,0,0);-ms-transform:translate3d(-10px,0,0);-o-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}.easingslider .easingslider-next.has-hover{-webkit-transform:translate3d(10px,0,0);-moz-transform:translate3d(10px,0,0);-ms-transform:translate3d(10px,0,0);-o-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}.easingslider:hover .easingslider-next.has-hover,.easingslider:hover .easingslider-prev.has-hover{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.easingslider-pagination{position:absolute;z-index:40;opacity:0;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-ms-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease}.easingslider-pagination.inside.bottom-left{bottom:10px;left:10px}.easingslider-pagination.inside.bottom-right{bottom:10px;right:10px}.easingslider-pagination.inside.bottom-center{bottom:10px;left:0;width:100%;text-align:center}.easingslider-pagination.inside.top-left{top:10px;left:10px}.easingslider-pagination.inside.top-right{top:10px;right:10px}.easingslider-pagination.inside.top-center{top:10px;left:0;width:100%;text-align:center}.easingslider-pagination.outside.bottom-left{bottom:-25px;left:0;padding-top:20px}.easingslider-pagination.outside.bottom-right{bottom:-25px;right:0;padding-top:20px}.easingslider-pagination.outside.bottom-center{bottom:-25px;left:0;width:100%;text-align:center;padding-top:20px}.easingslider-pagination.outside.top-left{top:-25px;left:0;padding-bottom:20px}.easingslider-pagination.outside.top-right{top:-25px;right:0;padding-bottom:20px}.easingslider-pagination.outside.top-center{top:-25px;left:0;width:100%;text-align:center;padding-bottom:20px}.easingslider-pagination .easingslider-icon{width:15px;height:15px;margin:0;padding:0;background-image:url(../images/nav-icon-inactive.png);background-repeat:no-repeat;background-position:0 0;display:inline-block;zoom:1;z-index:40;cursor:pointer}.easingslider-pagination .easingslider-icon:last-child{margin-right:0}.easingslider-pagination .easingslider-icon.active{background-image:url(../images/nav-icon-active.png)}.easingslider .easingslider-pagination.has-hover{opacity:0}.easingslider:hover .easingslider-pagination.has-hover{opacity:1}.easingslider.use-fade .easingslider-slide.next-in,.easingslider.use-fade .easingslider-slide.prev-in{-webkit-animation:fadeIn .3s ease;-moz-animation:fadeIn .3s ease;-ms-animation:fadeIn .3s ease;-o-animation:fadeIn .3s ease;animation:fadeIn .3s ease}._easingslider.use-fade .easingslider-slide.next-out,._easingslider.use-fade .easingslider-slide.prev-out{-webkit-animation:fadeOut .3s ease;-moz-animation:fadeOut .3s ease;-ms-animation:fadeOut .3s ease;-o-animation:fadeOut .3s ease;animation:fadeOut .3s ease}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-moz-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-ms-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-o-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-moz-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-ms-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-o-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.easingslider.use-slide .easingslider-viewport{overflow:hidden}.easingslider.use-slide .easingslider-slide.next-in{-webkit-animation:slideNextIn .3s ease;-moz-animation:slideNextIn .3s ease;-ms-animation:slideNextIn .3s ease;-o-animation:slideNextIn .3s ease;animation:slideNextIn .3s ease}.easingslider.use-slide .easingslider-slide.next-out{-webkit-animation:slideNextOut .3s ease;-moz-animation:slideNextOut .3s ease;-ms-animation:slideNextOut .3s ease;-o-animation:slideNextOut .3s ease;animation:slideNextOut .3s ease}.easingslider.use-slide .easingslider-slide.prev-out{-webkit-animation:slidePrevOut .3s ease;-moz-animation:slidePrevOut .3s ease;-ms-animation:slidePrevOut .3s ease;-o-animation:slidePrevOut .3s ease;animation:slidePrevOut .3s ease}.easingslider.use-slide .easingslider-slide.prev-in{-webkit-animation:slidePrevIn .3s ease;-moz-animation:slidePrevIn .3s ease;-ms-animation:slidePrevIn .3s ease;-o-animation:slidePrevIn .3s ease;animation:slidePrevIn .3s ease}@-webkit-keyframes slideNextIn{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{-webkit-transform:none;transform:none}}@-moz-keyframes slideNextIn{0%{-moz-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{-moz-transform:none;transform:none}}@-ms-keyframes slideNextIn{0%{-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{-ms-transform:none;transform:none}}@-o-keyframes slideNextIn{0%{-o-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{-o-transform:none;transform:none}}@keyframes slideNextIn{0%{transform:translate3d(100%,0,0)}100%{transform:none}}@-webkit-keyframes slideNextOut{0%{-webkit-transform:none;transform:none}100%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@-moz-keyframes slideNextOut{0%{-moz-transform:none;transform:none}100%{-moz-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@-ms-keyframes slideNextOut{0%{-ms-transform:none;transform:none}100%{-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@-o-keyframes slideNextOut{0%{-o-transform:none;transform:none}100%{-o-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideNextOut{0%{transform:none}100%{transform:translate3d(100%,0,0)}}@-webkit-keyframes slidePrevOut{0%{-webkit-transform:none;transform:none}100%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@-moz-keyframes slidePrevOut{0%{-moz-transform:none;transform:none}100%{-moz-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@-ms-keyframes slidePrevOut{0%{-ms-transform:none;transform:none}100%{-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@-o-keyframes slidePrevOut{0%{-o-transform:none;transform:none}100%{-o-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slidePrevOut{0%{transform:none}100%{transform:translate3d(-100%,0,0)}}@-webkit-keyframes slidePrevIn{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{-webkit-transform:none;transform:none}}@-moz-keyframes slidePrevIn{0%{-moz-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{-moz-transform:none;transform:none}}@-ms-keyframes slidePrevIn{0%{-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{-ms-transform:none;transform:none}}@-o-keyframes slidePrevIn{0%{-o-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{-o-transform:none;transform:none}}@keyframes slidePrevIn{0%{transform:translate3d(-100%,0,0)}100%{transform:none}}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min--moz-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (min-device-pixel-ratio:2),only screen and (min-resolution:192dpi),only screen and (min-resolution:2dppx){.easingslider-preload{background-image:url(../images/loading@2x.gif);background-size:24px 24px}.easingslider-play{background-image:url(../images/nav-play@2x.png);background-size:40px 40px}.easingslider-arrows.easingslider-next{background-image:url(../images/nav-arrow-next@2x.png);background-size:30px 30px}.easingslider-arrows.easingslider-prev{background-image:url(../images/nav-arrow-prev@2x.png);background-size:30px 30px}.easingslider .easingslider-icon{background-image:url(../images/nav-icon-inactive@2x.png);background-size:14px 14px}.easingslider .easingslider-icon.active{background-image:url(../images/nav-icon-active@2x.png);background-size:14px 14px}}
 
css/editor-pages.min.css DELETED
@@ -1 +0,0 @@
1
- .clearfix::after,.clearfix::before{display:table;content:'';line-height:0}.clearfix::after{clear:both}.updated.notice{border-color:#ffba00!important}.wp-list-table .column-ID{width:4em}.thumbnail .action .details-url{width:100%;max-width:700px}.image-details .media-modal{left:30px!important;right:30px!important}.attachment-info .settings{border-bottom-width:0!important}.attachment-info .settings h3{margin:10px 0;position:relative;font-weight:700;text-transform:uppercase;font-size:12px;color:#666}.attachment-info .setting .link-options{width:65%;float:right;margin:1px}.attachment-info .setting .link-options input[type=text]{width:98%;float:none;margin:5px 0 0}.attachment-info .setting .link-options label{margin-top:5px}.attachment-info .setting .link-options input[type=checkbox]{margin:-1px 5px 0 0!important}.attachment-info .column-settings h3.no-border{border-top-width:0;padding-top:0}.description{font-size:11px!important;font-style:italic!important;display:block!important;color:#777!important;padding:5px 0!important}.media-modal .description{margin-top:10px!important}.media-modal .media-embed .thumbnail{max-height:none;max-width:none}.media-modal .media-embed .thumbnail img{max-height:none;max-width:1000px;width:100%}.list{margin:0 0 20px 20px!important}.list li{font-size:11px!important;color:#777!important}.toolbar-container .media-toolbar{-webkit-box-shadow:0 1px 1px rgba(0,0,0,.04);-moz-box-shadow:0 1px 1px rgba(0,0,0,.04);box-shadow:0 1px 1px rgba(0,0,0,.04);border:1px solid #e5e5e5;margin-top:10px;margin-bottom:15px;position:relative;height:auto}.toolbar-container .media-toolbar .media-toolbar-primary,.toolbar-container .media-toolbar .media-toolbar-secondary{max-width:50%;min-width:384px}.toolbar-container .media-toolbar .media-toolbar-primary{text-align:right}.toolbar-container .media-toolbar .media-button{margin-top:10px;margin-bottom:10px}.toolbar-container .media-toolbar .randomize{float:none;margin-top:10px;margin-bottom:10px;line-height:30px;display:inline-block}.toolbar-container .media-toolbar .randomize input[type=checkbox]{margin-top:-2px;margin-right:8px}.toolbar-container .media-toolbar .media-button{float:none}.toolbar-container .title-form{float:left;margin-top:9px}.toolbar-container .title-form .media-button{margin-top:1px;margin-left:0}.toolbar-container .title-form label{vertical-align:top;font-weight:700;line-height:32px;margin:0 5px 0 0}.toolbar-container .title-form input[type=text]{margin:0;padding:3px 5px;width:280px;font-size:16px;font-weight:300;line-height:1.5}.main-container{margin-right:300px}.slides-container{width:100%;float:left}.settings-container{float:right;margin-right:-300px;width:280px}.settings-container .banners a{display:block;margin-bottom:15px}.settings-container .widgets-holder-wrap{margin-top:0;margin-bottom:10px}.settings-container .sidebar-name{border-bottom:1px solid #eee}.settings-container .sidebar-name h3{padding:15px}.settings-container .sidebar-name-arrow:before{top:4px!important}.settings-container.closed .sidebar-name{border-width:0}.settings-container .sidebar-content{border-width:0 1px 1px;border-style:none solid solid;border-color:#fff;-webkit-border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;padding:10px 15px;min-height:20px}.settings-container .sidebar-content .divider{margin-bottom:0}.settings-container .sidebar-content .field,.settings-container .sidebar-content .radio{width:100%;margin:1em 0}.settings-container .sidebar-content .field span{font-weight:700;display:block}.settings-container .sidebar-content .field{float:left}.settings-container .sidebar-content .field input[type=text],.settings-container .sidebar-content .field input[type=number],.settings-container .sidebar-content .field select{width:90%}.settings-container .sidebar-content .field input[type=checkbox]{margin-right:4px}.settings-container .sidebar-content .radio>span{font-weight:700;float:left}.settings-container .sidebar-content .radio .buttons{float:right}.settings-container .sidebar-content .radio .buttons label{margin-right:10px}.settings-container .sidebar-content .radio .buttons input{margin-top:0;margin-right:2px}.settings-container .sidebar-content .advanced-options.hidden{display:none!important}.settings-container .sidebar-content .show-advanced-options{margin:15px 0;font-weight:700;display:block}.settings-container .sidebar-content .manage-slides-buttons .dashicons-plus{line-height:28px}.settings-container .sidebar-content .manage-slides-buttons .dashicons-trash{line-height:27px}.settings-container .sidebar-content .misc-pub-section{padding-left:0;padding-right:0}.settings-container .dimension-settings .field.half{width:45%}.settings-container .dimension-settings .field.half:first-child{margin-right:5%}#slides-browser .ui-sortable{min-height:300px}#slides-browser .spinner{float:left;display:inline}#slides-browser .attachment .toolbar{display:none;text-align:left;position:absolute;top:0;left:0}#slides-browser .attachment:hover .toolbar{display:block}#slides-browser .attachment .toolbar i{-webkit-box-shadow:0 1px 3px rgba(0,0,0,.5);-moz-box-shadow:0 1px 3px rgba(0,0,0,.5);box-shadow:0 1px 3px rgba(0,0,0,.5);position:relative;margin-top:7px;margin-left:7px;padding:2px;font-size:30px;height:30px;width:30px;background:#000;background:rgba(0,0,0,.9);cursor:pointer;z-index:9999;color:#fff}#slides-browser .attachment .toolbar i:hover{-webkit-box-shadow:0 1px 3px rgba(0,0,0,.8);-moz-box-shadow:0 1px 3px rgba(0,0,0,.8);box-shadow:0 1px 3px rgba(0,0,0,.8);background-color:#000;color:#2ea2cc}#slides-browser .attachment .check div{background-position:21px 0}#slides-browser .attachment.selected .check div{background-position:-21px 0}#slides-browser .attachment.selected .check:hover div{background-position:-60px 0}#slides-browser .thumbnail img{width:100%}#slides-browser .thumbnail img.icon{width:auto}#slides-browser .thumbnail:hover .delete-button{opacity:1}@media only screen and (max-width:1040px){.toolbar-container .media-toolbar .media-toolbar-primary,.toolbar-container .media-toolbar .media-toolbar-secondary{max-width:100%;float:none}.toolbar-container .media-toolbar .media-toolbar-primary{text-align:left}}@media only screen and (max-width:900px){.attachment-info .setting .link-options{width:100%;float:none}}@media only screen and (max-width:640px){.image-details .media-modal{left:0!important;right:0!important}.image-details .media-modal input[type=text],.image-details .media-modal input[type=url],.image-details .media-modal select,.image-details .media-modal textarea{font-size:16px;padding:6px 10px}.attachment-info .media-modal{left:0!important;right:0!important}.attachment-info .setting .link-options{width:100%;float:none;margin:1px}.attachment-info .setting .link-options label{margin-top:8px}.toolbar-container .media-toolbar .media-toolbar-primary{margin-bottom:15px}.toolbar-container .media-toolbar .media-toolbar-secondary{margin-top:10px}.toolbar-container .media-toolbar .randomize{display:block;float:none}.toolbar-container .media-toolbar .media-button{float:none;margin:0 10px 10px 0}.main-container{margin-right:0}.slides-container{float:none}#slides-browser .ui-sortable{min-height:100px}.settings-container{float:none;margin-top:20px;margin-right:0;width:100%}}
 
css/extensions-page.css DELETED
@@ -1,34 +0,0 @@
1
- .wrap > p {
2
- margin-bottom: 25px;
3
- }
4
-
5
- .updated.notice {
6
- border-color: #ffba00 !important;
7
- }
8
-
9
- .extension {
10
- background: #f1f1f1;
11
- border: 1px solid #ccc;
12
- margin: 0 20px 20px 0;
13
- padding: 15px;
14
- float: left;
15
- width: 300px;
16
- height: 330px;
17
- position: relative;
18
- }
19
-
20
- .extension a {
21
- display: block;
22
- margin: -16px -16px 15px -16px;
23
- }
24
-
25
- .extension img {
26
- max-width: 100%;
27
- height: auto;
28
- }
29
-
30
- .extension .button-primary {
31
- position: absolute;
32
- bottom: 15px;
33
- left: 15px;
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/extensions-page.min.css DELETED
@@ -1 +0,0 @@
1
- .wrap>p{margin-bottom:25px}.updated.notice{border-color:#ffba00!important}.extension{background:#f1f1f1;border:1px solid #ccc;margin:0 20px 20px 0;padding:15px;float:left;width:300px;height:330px;position:relative}.extension a{display:block;margin:-16px -16px 15px}.extension img{max-width:100%;height:auto}.extension .button-primary{position:absolute;bottom:15px;left:15px}
 
css/settings-page.css DELETED
@@ -1,30 +0,0 @@
1
- .description {
2
- font-size: 11px !important;
3
- font-style: italic !important;
4
- display: block !important;
5
- color: #777 !important;
6
- padding: 5px 0 !important;
7
- }
8
-
9
- .form-table label span {
10
- margin-right: 15px;
11
- }
12
-
13
- .valid-license {
14
- position: relative;
15
- }
16
-
17
- .valid-license:after {
18
- content: "\f147";
19
- font-family: "Dashicons";
20
- position: absolute;
21
- top: 0;
22
- bottom: 0;
23
- right: 10px;
24
- color: #468847;
25
- font-size: 18px;
26
- }
27
-
28
- .updated.notice {
29
- border-color: #ffba00 !important;
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/settings-page.min.css DELETED
@@ -1 +0,0 @@
1
- .description{font-size:11px!important;font-style:italic!important;display:block!important;color:#777!important;padding:5px 0!important}.form-table label span{margin-right:15px}.valid-license{position:relative}.valid-license:after{content:"\f147";font-family:Dashicons;position:absolute;top:0;bottom:0;right:10px;color:#468847;font-size:18px}.updated.notice{border-color:#ffba00!important}
 
css/welcome-pages.css DELETED
@@ -1,44 +0,0 @@
1
- .easingslider-badge {
2
- position: absolute;
3
- top: 0;
4
- right: 0;
5
- height: 160px;
6
- width: 185px;
7
- padding-top: 100px;
8
- color: #abb6c5;
9
- font-weight: bold;
10
- font-size: 14px;
11
- text-align: center;
12
- margin: 0 -5px;
13
- background: url(../images/easingslider-badge.jpg) no-repeat;
14
- }
15
-
16
- .updated.notice {
17
- border-color: #ffba00 !important;
18
- }
19
-
20
- .about-wrap .changelog .about-text {
21
- margin-right: 0;
22
- margin-bottom: 50px;
23
- text-align: center;
24
- }
25
-
26
- .about-wrap .changelog .about-headline-callout.credits-headline {
27
- text-align: left;
28
- margin-bottom: 30px;
29
- }
30
-
31
- .about-wrap h4.wp-people-group {
32
- margin-top: 50px;
33
- }
34
-
35
- .about-wrap .welcome-screenshot {
36
- width: 100%;
37
- margin: 30px 0 20px 0 !important;
38
- }
39
-
40
- @media screen and (max-width: 782px) {
41
- .welcome-screenshot {
42
- margin-top: 0 !important;
43
- }
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/welcome-pages.min.css DELETED
@@ -1 +0,0 @@
1
- .easingslider-badge{position:absolute;top:0;right:0;height:160px;width:185px;padding-top:100px;color:#abb6c5;font-weight:700;font-size:14px;text-align:center;margin:0 -5px;background:url(../images/easingslider-badge.jpg) no-repeat}.updated.notice{border-color:#ffba00!important}.about-wrap .changelog .about-text{margin-right:0;margin-bottom:50px;text-align:center}.about-wrap .changelog .about-headline-callout.credits-headline{text-align:left;margin-bottom:30px}.about-wrap h4.wp-people-group{margin-top:50px}.about-wrap .welcome-screenshot{width:100%;margin:30px 0 20px!important}@media screen and (max-width:782px){.welcome-screenshot{margin-top:0!important}}
 
easing-slider.php CHANGED
@@ -1,393 +1,80 @@
1
  <?php
2
-
3
- /*
4
- Plugin Name: Easing Slider
5
- Plugin URI: http://easingslider.com/
6
- Version: 2.2.1.1
7
- Author: Matthew Ruddy
8
- Author URI: http://matthewruddy.com/
9
- Description: Easing Slider is an easy to use slider plugin for WordPress. Simple, lightweight & designed to get the job done, it allows you to get creating sliders without any difficulty.
10
- License: GNU General Public License v2.0 or later
11
- License URI: http://www.opensource.org/licenses/gpl-license.php
12
-
13
- Copyright 2015 Matthew Ruddy
14
-
15
- This program is free software; you can redistribute it and/or modify
16
- it under the terms of the GNU General Public License, version 2, as
17
- published by the Free Software Foundation.
18
-
19
- This program is distributed in the hope that it will be useful,
20
- but WITHOUT ANY WARRANTY; without even the implied warranty of
21
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
- GNU General Public License for more details.
23
-
24
- You should have received a copy of the GNU General Public License
25
- along with this program; if not, write to the Free Software
26
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
- */
28
 
29
  /**
30
  * Exit if accessed directly
31
  */
32
- if ( ! defined( 'ABSPATH' ) ) {
33
  exit;
34
  }
35
 
36
- // Let's go!
37
- if ( class_exists( 'Easing_Slider' ) ) {
38
- new Easing_Slider();
39
- }
40
-
41
  /**
42
- * Loads and defines the plugin functionality.
43
- *
44
- * @author Matthew Ruddy
45
  */
46
- class Easing_Slider {
47
-
48
- /**
49
- * Our plugin version
50
- *
51
- * @var string
52
- */
53
- public static $version = '2.2.1.1';
54
-
55
- /**
56
- * Our plugin file
57
- *
58
- * @var string
59
- */
60
- public static $file = __FILE__;
61
-
62
- /**
63
- * Constructor
64
- *
65
- * @return void
66
- */
67
- public function __construct() {
68
-
69
- // Activation and uninstall hooks
70
- register_activation_hook( __FILE__, array( __CLASS__, 'do_activation' ) );
71
- register_uninstall_hook( __FILE__, array( __CLASS__, 'do_uninstall' ) );
72
-
73
- // Load dependancies
74
- $this->load_dependancies();
75
-
76
- // Setup localization
77
- $this->set_locale();
78
-
79
- // Register post type
80
- $this->register_post_type();
81
-
82
- // Define hooks
83
- $this->define_hooks();
84
-
85
- /**
86
- * The customizer has been prepared for export as an "extension" in the near future.
87
- * To keep our current users happy and prepare them for the changes, we've bootstrapped the customizer
88
- * into the core plugin, alongside a notice informing them of these changes.
89
- *
90
- * Once the changeover is complete, this code will be removed.
91
- */
92
- $this->bootstrap_customizer();
93
-
94
- }
95
-
96
- /**
97
- * Activation
98
- *
99
- * @return void
100
- */
101
- public static function do_activation() {
102
-
103
- global $wp_version;
104
-
105
- // Deactivate the plugin if the WordPress version is below the minimum required.
106
- if ( version_compare( $wp_version, '4.0', '<' ) ) {
107
- deactivate_plugins( plugin_basename( __FILE__ ) );
108
- wp_die( __( sprintf( 'Sorry, but your version of WordPress, <strong>%s</strong>, is not supported. The plugin has been deactivated. <a href="%s">Return to the Dashboard.</a>', $wp_version, admin_url() ), 'easingslider' ) );
109
- return false;
110
- }
111
-
112
- // Add options
113
- add_option( 'easingslider_version', self::$version );
114
- add_option( 'easingslider_settings', (object) array(
115
- 'image_resizing' => false,
116
- 'load_assets' => 'header',
117
- 'remove_data' => false
118
- ) );
119
-
120
- // Let's flush rewrite rules as we're using a custom post type
121
- flush_rewrite_rules();
122
-
123
- // Trigger hooks
124
- do_action( 'easingslider_activate' );
125
-
126
- }
127
-
128
- /**
129
- * Uninstall
130
- *
131
- * @return void
132
- */
133
- public static function do_uninstall() {
134
-
135
- // Get the settings
136
- $settings = get_option( 'easingslider_settings' );
137
-
138
- // If enabled, remove the plugin data
139
- if ( $settings->remove_data ) {
140
-
141
- // Delete all of the sliders
142
- foreach ( ES_Slider::all() as $slider ) {
143
- ES_Slider::delete( $slider->ID );
144
- }
145
-
146
- // Delete options
147
- delete_option( 'easingslider_version' );
148
- delete_option( 'easingslider_settings' );
149
-
150
- // Remove data hook
151
- do_action( 'easingslider_remove_data' );
152
-
153
- }
154
-
155
- // Trigger hooks
156
- do_action( 'easingslider_uninstall' );
157
-
158
- }
159
-
160
- /**
161
- * Load dependancies
162
- *
163
- * @return void
164
- */
165
- protected function load_dependancies() {
166
-
167
- // The file responsible for loading our helpers
168
- require_once plugin_dir_path( __FILE__ ) . 'includes/helpers.php';
169
-
170
- // The class responsible for defining our admin editor
171
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-editor-pages.php';
172
-
173
- // The class responsible for discovering extensions
174
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-extensions-page.php';
175
-
176
- // The class responsible for resizing attachment images
177
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-image-resizer.php';
178
-
179
- // The class responsible for importing legacy settings
180
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-legacy.php';
181
-
182
- // The class responsible for adding our plugin toplevel menu
183
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-menu.php';
184
-
185
- // The class responsible for managing our migrations
186
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-migrations.php';
187
-
188
- // The class responsible for defining our admin settings
189
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-settings-page.php';
190
-
191
- // The class responsible for handling plugin shortcodes
192
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-shortcode.php';
193
 
194
- // The class responsible for managing our public facing functionality
195
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-slider.php';
196
-
197
- // The class responsible for handling our slider list table
198
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-sliders-list-table.php';
199
-
200
- // The class responsible for extension updates and licensing
201
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-update-manager.php';
202
-
203
- // The class responsible for displaying our welcome page(s)
204
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-welcome-pages.php';
205
-
206
- // The class responsible for adding a widget for displaying a slider
207
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-widget.php';
208
-
209
- }
210
-
211
- /**
212
- * Set locale
213
- *
214
- * @return void
215
- */
216
- protected function set_locale() {
217
-
218
- // Load plugin textdomain
219
- load_plugin_textdomain( 'easing-slider', false, dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' );
220
-
221
- }
222
-
223
- /**
224
- * Register our "easingslider" post type
225
- *
226
- * @return void
227
- */
228
- protected function register_post_type() {
229
-
230
- // Register the post type
231
- register_post_type( 'easingslider', array(
232
- 'query_var' => false,
233
- 'rewrite' => false,
234
- 'public' => true,
235
- 'exclude_from_search' => true,
236
- 'publicly_queryable' => false,
237
- 'show_in_nav_menus' => false,
238
- 'show_ui' => false,
239
- 'labels' => array(
240
- 'name' => __( 'Sliders', 'easingslider' )
241
- )
242
- ) );
243
-
244
- }
245
-
246
- /**
247
- * Define menu hooks
248
- *
249
- * @return void
250
- */
251
- protected function define_hooks() {
252
-
253
- // Initiate components
254
- $editor_pages = new ES_Editor_Pages();
255
- $extensions_page = new ES_Extensions_Page();
256
- $image_resizer = new ES_Image_Resizer();
257
- $legacy = new ES_Legacy();
258
- $menu = new ES_Menu();
259
- $migrations = new ES_Migrations();
260
- $settings_page = new ES_Settings_Page();
261
- $shortcode = new ES_Shortcode();
262
- $slider = new ES_Slider();
263
- $welcome_pages = new ES_Welcome_Pages();
264
- $widget = new ES_Widget();
265
-
266
- /**
267
- * Hook everything, "connect all the dots"!
268
- *
269
- * All of these actions connect the various parts of our plugin together.
270
- * The idea behind this is to keep each "component" as separate as possible, decoupled from other components.
271
- *
272
- * These hooks bridge the gaps.
273
- */
274
- add_action( 'admin_init', array( $editor_pages, 'register_assets' ) );
275
- add_action( 'admin_menu', array( $editor_pages, 'add_edit_page' ), 999 );
276
- add_action( 'admin_menu', array( $editor_pages, 'add_publish_page' ), 999 );
277
- add_action( 'easingslider_activate', array( $editor_pages, 'add_capabilities' ) );
278
- add_action( 'easingslider_remove_data', array( $editor_pages, 'remove_capabilities' ) );
279
- add_filter( 'set-screen-option', array( $editor_pages, 'set_screen_option' ), 10, 3 );
280
-
281
- add_action( 'admin_init', array( $extensions_page, 'register_assets' ) );
282
- add_action( 'admin_menu', array( $extensions_page, 'add_submenu_page' ), 99999 );
283
- add_action( 'easingslider_activate', array( $extensions_page, 'add_capabilities' ) );
284
- add_action( 'easingslider_remove_data', array( $extensions_page, 'remove_capabilities' ) );
285
-
286
- add_action( 'delete_attachment', array( $image_resizer, 'delete_resized_attachments' ) );
287
-
288
- add_action( 'init', array( $legacy, 'lite_upgrade_from_200' ), 1 );
289
- add_action( 'init', array( $legacy, 'lite_upgrade_from_100' ), 2 );
290
- add_action( 'init', array( $legacy, 'pro_upgrade_from_200' ), 1 );
291
- add_action( 'init', array( $legacy, 'pro_upgrade_from_100' ), 2 );
292
- add_action( 'easingslider_remove_data', array( $legacy, 'remove_options' ) );
293
- add_action( 'easingslider_delete_slider', array( $legacy, 'delete_lite_slider' ) );
294
- add_action( 'easingslider_delete_slider', array( $legacy, 'delete_pro_slider' ) );
295
- add_action( 'easingslider_pre_redirect_to_welcome', array( $legacy, 'redirect_to_whats_new' ) );
296
- add_action( 'easingslider_display_shortcode', array( $legacy, 'handle_lite_shortcode' ) );
297
- add_shortcode( 'easingsliderlite', array( $legacy, 'do_lite_shortcode' ) );
298
- add_shortcode( 'easingsliderpro', array( $legacy, 'do_pro_shortcode' ) );
299
- add_shortcode( 'rivasliderpro', array( $legacy, 'do_pro_shortcode' ) );
300
-
301
- add_action( 'admin_menu', array( $menu, 'add_toplevel_menu' ) );
302
-
303
- add_action( 'init', array( $migrations, 'do_migrations' ) );
304
- add_action( 'easingslider_update_plugin', array( $migrations, 'migrate_to_22' ) );
305
- add_action( 'easingslider_update_plugin', array( $migrations, 'update_version' ), 999 );
306
-
307
- add_action( 'admin_init', array( $settings_page, 'register_assets' ) );
308
- add_action( 'admin_menu', array( $settings_page, 'add_submenu_page' ), 999 );
309
- add_action( 'easingslider_activate', array( $settings_page, 'add_capabilities' ) );
310
- add_action( 'easingslider_remove_data', array( $settings_page, 'remove_capabilities' ) );
311
-
312
- add_action( 'admin_footer', array( $shortcode, 'print_media_thickbox' ) );
313
- add_action( 'media_buttons', array( $shortcode, 'print_media_button' ), 999 );
314
- add_shortcode( 'easingslider', array( $shortcode, 'render' ) );
315
-
316
- add_action( 'init', array( $slider, 'register_assets' ) );
317
- add_action( 'wp_enqueue_scripts', array( $slider, 'enqueue_assets' ) );
318
- add_filter( 'easingslider_pre_save_slider', array( $slider, 'no_title' ) );
319
- add_filter( 'easingslider_pre_display_slider', array( $slider, 'maybe_randomize' ) );
320
- add_filter( 'easingslider_get_html_data', array( $slider, 'cleanup_data' ) );
321
- add_filter( 'easingslider_before_display_slider', array( $slider, 'no_script' ), 10, 2 );
322
- add_filter( 'easingslider_before_slider_content', array( $slider, 'add_preload' ), 10, 2 );
323
- add_filter( 'easingslider_display_image_slide', array( $slider, 'add_image' ), 10, 3 );
324
- add_filter( 'easingslider_modify_image_url', array( $slider, 'resize_image' ), 10, 3 );
325
- add_filter( 'easingslider_before_display_slide', array( $slider, 'open_link' ), 10, 3 );
326
- add_filter( 'easingslider_after_display_slide', array( $slider, 'close_link' ), 10, 3 );
327
-
328
- add_action( 'admin_init', array( $welcome_pages, 'register_assets' ) );
329
- add_action( 'admin_init', array( $welcome_pages, 'redirect_to_welcome' ) );
330
- add_action( 'admin_menu', array( $welcome_pages, 'add_dashboard_pages' ) );
331
- add_action( 'admin_head', array( $welcome_pages, 'hide_individual_pages' ) );
332
- add_action( 'easingslider_activate', array( $welcome_pages, 'set_redirect_transient' ) );
333
-
334
- add_action( 'widgets_init', array( $widget, 'register' ) );
335
-
336
- }
337
-
338
- /**
339
- * This method bootstraps the customization functionality, which will soon be exported into an extension.
340
- * If the "Visual Customizer" extension is already activated, this method won't do anything.
341
- *
342
- * This method will be removed in due course.
343
- *
344
- * @return void
345
- */
346
- public function bootstrap_customizer() {
347
-
348
- // Bail if the customizer has already been loaded
349
- if ( ! class_exists( 'ES_Customizer' ) ) {
350
-
351
- // Load the customizer components
352
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-customizations.php';
353
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-customizer-legacy.php';
354
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-customizer-notice.php';
355
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-es-customizer.php';
356
-
357
- // Initiate components
358
- $customizations = new ES_Customizations();
359
- $customizer_legacy = new ES_Customizer_Legacy();
360
- $customizer_notice = new ES_Customizer_Notice();
361
- $customizer = new ES_Customizer();
362
-
363
- /**
364
- * Define hooks
365
- */
366
- add_filter( 'easingslider_metadata_defaults', array( $customizations, 'merge_defaults' ) );
367
- add_filter( 'easingslider_get_container_data', array( $customizations, 'remove_data' ), 10, 2 );
368
- add_filter( 'easingslider_after_display_slider', array( $customizations, 'drop_shadow' ), 10, 2 );
369
- add_filter( 'easingslider_before_display_slider', array( $customizations, 'display_styling' ), 10, 2 );
370
-
371
- add_action( 'init', array( $customizer_legacy, 'lite_upgrade_from_200' ), 1 );
372
- add_action( 'init', array( $customizer_legacy, 'lite_upgrade_from_100' ), 2 );
373
- add_action( 'init', array( $customizer_legacy, 'pro_upgrade_from_200' ) );
374
- add_action( 'easingslider_remove_data', array( $customizer_legacy, 'remove_options' ) );
375
-
376
- /**
377
- * We're not quite ready to display this notice yet.
378
- * This code will be uncommented when the customizer is available as an extension.
379
- */
380
- // add_action( 'admin_init', array( $customizer_notice, 'handle_dismiss' ) );
381
- // add_action( 'admin_init', array( $customizer_notice, 'display' ), 999 );
382
- // add_action( 'easingslider_uninstall', array( $customizer_notice, 'unset_flag' ) );
383
 
384
- add_action( 'admin_init', array( $customizer, 'register_assets' ) );
385
- add_action( 'admin_menu', array( $customizer, 'add_submenu_page' ), 9999 );
386
- add_action( 'easingslider_activate', array( $customizer, 'add_capabilities' ) );
387
- add_action( 'easingslider_remove_data', array( $customizer, 'remove_capabilities' ) );
 
 
 
 
 
 
 
 
 
 
388
 
389
- }
 
 
 
390
 
391
- }
 
 
 
 
 
 
 
 
 
392
 
393
- }
 
 
 
1
  <?php
2
+ /**
3
+ * Plugin Name: Easing Slider
4
+ * Plugin URI: http://easingslider.com/
5
+ * Description: A simple WordPress plugin for creating beautiful sliders.
6
+ * Version: 3.0.0
7
+ * Author: Matthew Ruddy
8
+ * Author URI: http://matthewruddy.com
9
+ * License: GPL2
10
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
+ * Domain Path: /languages
12
+ * Text Domain: easingslider
13
+ *
14
+ * @package Easing Slider
15
+ * @author Matthew Ruddy
16
+ */
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  /**
19
  * Exit if accessed directly
20
  */
21
+ if ( ! defined('ABSPATH')) {
22
  exit;
23
  }
24
 
 
 
 
 
 
25
  /**
26
+ * Define constants
 
 
27
  */
28
+ define('EASINGSLIDER_VERSION', '3.0.0');
29
+ define('EASINGSLIDER_NAME', 'Easing Slider');
30
+ define('EASINGSLIDER_API_URL', 'http://easingslider.com/');
31
+ define('EASINGSLIDER_PLUGIN_DIR', plugin_dir_path(__FILE__));
32
+ define('EASINGSLIDER_PLUGIN_URL', plugin_dir_url(__FILE__));
33
+ define('EASINGSLIDER_PLUGIN_FILE', __FILE__);
34
+ define('EASINGSLIDER_ASSETS_DIR', EASINGSLIDER_PLUGIN_DIR .'assets/');
35
+ define('EASINGSLIDER_ASSETS_URL', EASINGSLIDER_PLUGIN_URL .'assets/');
36
+ define('EASINGSLIDER_RESOURCES_DIR', EASINGSLIDER_PLUGIN_DIR .'resources/');
37
+ define('EASINGSLIDER_RESOURCES_URL', EASINGSLIDER_PLUGIN_URL .'resources/');
38
+ define('EASINGSLIDER_TEMPLATES_DIR', EASINGSLIDER_PLUGIN_DIR .'templates/');
39
+ define('EASINGSLIDER_TEMPLATES_URL', EASINGSLIDER_PLUGIN_URL .'templates/');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ /**
42
+ * Autoload dependencies
43
+ */
44
+ require_once('vendor/autoload.php');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
+ /**
47
+ * The main function responsible for returning the one true Easing_Slider instance to functions everywhere.
48
+ *
49
+ * Use this function like you would a global variable, except without needing
50
+ * to declare the global.
51
+ *
52
+ * Example: <?php $easing_slider = Easing_Slider(); ?>
53
+ *
54
+ * @return Easing_Slider
55
+ */
56
+ function Easing_Slider()
57
+ {
58
+ return \EasingSlider\Plugin\Plugin::instance();
59
+ }
60
 
61
+ /**
62
+ * Let's go!
63
+ */
64
+ Easing_Slider();
65
 
66
+ /**
67
+ * Activator
68
+ *
69
+ * @return void
70
+ */
71
+ function easingslider_activate()
72
+ {
73
+ $activator = Easing_Slider()->activator();
74
+ $activator->activate();
75
+ }
76
 
77
+ /**
78
+ * Register activation hook
79
+ */
80
+ register_activation_hook(__FILE__, 'easingslider_activate');
images/nav-play.png DELETED
Binary file
images/nav-play@2x.png DELETED
Binary file
includes/class-es-customizations.php DELETED
@@ -1,262 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Defines & loads our customizations
12
- *
13
- * @author Matthew Ruddy
14
- */
15
- class ES_Customizations {
16
-
17
- /**
18
- * Returns the defaults for our slider "customizations" metadata
19
- *
20
- * @return object
21
- */
22
- public function defaults() {
23
-
24
- $plugin_url = plugins_url( 'easing-slider/images' );
25
-
26
- return (object) array(
27
- 'arrows' => (object) array(
28
- 'next' => "{$plugin_url}/nav-arrow-next.png",
29
- 'prev' => "{$plugin_url}/nav-arrow-prev.png",
30
- 'width' => 30,
31
- 'height' => 30
32
- ),
33
- 'pagination' => (object) array(
34
- 'inactive' => "{$plugin_url}/nav-icon-inactive.png",
35
- 'active' => "{$plugin_url}/nav-icon-active.png",
36
- 'width' => 15,
37
- 'height' => 15
38
- ),
39
- 'border' => (object) array(
40
- 'color' => '#000000',
41
- 'width' => 0,
42
- 'radius' => 0
43
- ),
44
- 'shadow' => (object) array(
45
- 'enabled' => false,
46
- 'image' => "{$plugin_url}/shadow.png"
47
- )
48
- );
49
-
50
- }
51
-
52
- /**
53
- * Merges in our default slider "customizations" metadata
54
- *
55
- * @param array $metadata_defaults The default metadata
56
- * @return array
57
- */
58
- public function merge_defaults( $metadata_defaults ) {
59
-
60
- $defaults = array( 'customizations' => $this->defaults() );
61
-
62
- return array_merge( $metadata_defaults, $defaults );
63
-
64
- }
65
-
66
- /**
67
- * Displays the customization styling for a slider
68
- *
69
- * @param string $html The slider HTML
70
- * @param ES_Slider $slider The slider object
71
- * @return void
72
- */
73
- public function display_styling( $html, $slider ) {
74
-
75
- // Get the defaults & customizations
76
- $defaults = $this->defaults();
77
- $customizations = $slider->customizations;
78
-
79
- // Bail if we have no customizations
80
- if ( $defaults == $customizations ) {
81
- return $html;
82
- }
83
-
84
- // Open the output
85
- $html .= "<style type=\"text/css\">";
86
-
87
- // Next & Previous Arrows
88
- if ( $defaults->arrows != $customizations->arrows ) {
89
-
90
- // Width & height
91
- $html .= ".easingslider-{$slider->ID} .easingslider-arrows { ";
92
- if ( $defaults->arrows->width != $customizations->arrows->width ) {
93
- $html .= "width: {$customizations->arrows->width}px; ";
94
- }
95
- if ( $defaults->arrows->height != $customizations->arrows->height ) {
96
- $margin_top = ( $customizations->arrows->height / 2 );
97
-
98
- $html .= "height: {$customizations->arrows->height}px; ";
99
- $html .= "margin-top: {$margin_top}px; ";
100
- }
101
- $html .= "}";
102
-
103
- // "Next" image
104
- if ( $defaults->arrows->next != $customizations->arrows->next ) {
105
- $html .= ".easingslider-{$slider->ID} .easingslider-next { ";
106
- $html .= "background-image: url({$customizations->arrows->next}); ";
107
- $html .= "}";
108
- }
109
-
110
- // "Prev" image
111
- if ( $defaults->arrows->prev != $customizations->arrows->prev ) {
112
- $html .= ".easingslider-{$slider->ID} .easingslider-prev { ";
113
- $html .= "background-image: url({$customizations->arrows->prev}); ";
114
- $html .= "}";
115
- }
116
-
117
- }
118
-
119
- // Pagination
120
- if ( $defaults->pagination != $customizations->pagination ) {
121
-
122
- // Width & height, and "inactive" image
123
- $html .= ".easingslider-{$slider->ID} .easingslider-icon { ";
124
- if ( $defaults->pagination->width != $customizations->pagination->width ) {
125
- $html .= "width: {$customizations->pagination->width}px; ";
126
- }
127
- if ( $defaults->pagination->height != $customizations->pagination->height ) {
128
- $html .= "height: {$customizations->pagination->height}px; ";
129
- }
130
- if ( $defaults->pagination->inactive != $customizations->pagination->inactive ) {
131
- $html .= "background-image: url({$customizations->pagination->inactive}); ";
132
- }
133
- $html .= "}";
134
-
135
- // "Active" image
136
- if ( $defaults->pagination->active != $customizations->pagination->active ) {
137
- $html .= ".easingslider-{$slider->ID} .easingslider-icon.active { ";
138
- $html .= "background-image: url({$customizations->pagination->active}); ";
139
- $html .= "}";
140
- }
141
-
142
- }
143
-
144
- // Border
145
- if ( $defaults->border != $customizations->border ) {
146
- $html .= ".easingslider-{$slider->ID} { ";
147
-
148
- // Color
149
- if ( $defaults->border->color != $customizations->border->color ) {
150
- $html .= "border-color: {$customizations->border->color}; ";
151
- }
152
-
153
- // Width
154
- if ( $defaults->border->width != $customizations->border->width ) {
155
- $html .= "border-width: {$customizations->border->width}px; ";
156
- $html .= "border-style: solid; ";
157
- }
158
-
159
- // Radius
160
- if ( $defaults->border->radius != $customizations->border->radius ) {
161
- $html .= "-webkit-border-radius: {$customizations->border->radius}px; ";
162
- $html .= "-moz-border-radius: {$customizations->border->radius}px; ";
163
- $html .= "border-radius: {$customizations->border->radius}px; ";
164
- }
165
-
166
- $html .= "}";
167
- }
168
-
169
- // Drop Shadow (if enabled)
170
- if ( $customizations->shadow->enabled && ! empty( $customizations->shadow->image ) ) {
171
- $html .= ".easingslider-shadow-{$slider->ID} { ";
172
-
173
- // Make responsive or fixed
174
- if ( $slider->dimensions->responsive ) {
175
- $html .= "width: 100%; ";
176
- $html .= "max-width: {$slider->dimensions->width}px; ";
177
- }
178
- else {
179
- $html .= "width: {$slider->dimensions->width}px; ";
180
- }
181
-
182
- $html .= "}";
183
- }
184
-
185
-
186
- // Close the output
187
- $html .= "</style>";
188
-
189
- return $html;
190
-
191
- }
192
-
193
- /**
194
- * Removes customizations from slider container data (it's not needed).
195
- *
196
- * @param array $metadata The array of metadata
197
- * @return array
198
- */
199
- public function remove_data( $metadata ) {
200
-
201
- // Remove the data
202
- unset( $metadata['customizations'] );
203
-
204
- return $metadata;
205
-
206
- }
207
-
208
- /**
209
- * Displays a drop shadow beneath the slider
210
- *
211
- * @param string $html The slider HTML
212
- * @param ES_Slider $slider The slider object
213
- * @return string
214
- */
215
- public function drop_shadow( $html, $slider ) {
216
-
217
- // Get the customizations
218
- $customizations = $slider->customizations;
219
-
220
- /**
221
- * If we are on the "customizer" page, we always want to render the shadow.
222
- * This allow us to toggle it with our live preview. Can't be achieved as easily otherwise.
223
- *
224
- * We also add some CSS to ensure it is hidden if currently disabled, but still printed in the slider's HTML.
225
- */
226
- if ( isset( $_GET['page'] ) && 'easingslider_manage_customizations' == $_GET['page'] ) {
227
-
228
- // No need for this if the shadow is already enabled
229
- if ( ! $customizations->shadow->enabled ) {
230
- $customizations->shadow->enabled = true;
231
-
232
- // Add the HTML
233
- $html .= "<style type=\"text/css\">";
234
- $html .= ".easingslider-shadow { ";
235
- $html .= "display: none; ";
236
-
237
- // Make responsive or fixed
238
- if ( $slider->dimensions->responsive ) {
239
- $html .= "width: 100%; ";
240
- $html .= "max-width: {$slider->dimensions->width}px; ";
241
- }
242
- else {
243
- $html .= "width: {$slider->dimensions->width}px; ";
244
- }
245
- $html .= "}";
246
- $html .= "</style>";
247
- }
248
-
249
- }
250
-
251
- // Render the shadow if enabled
252
- if ( $customizations->shadow->enabled && ! empty( $customizations->shadow->image ) ) {
253
- $html .= "<div class=\"easingslider-shadow easingslider-shadow-{$slider->ID}\">";
254
- $html .= "<img src=\"{$customizations->shadow->image}\" style=\"width: 100%;\" />";
255
- $html .= "</div>";
256
- }
257
-
258
- return $html;
259
-
260
- }
261
-
262
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-customizer-legacy.php DELETED
@@ -1,262 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * This class ensures a smooth transition from "Lite" or "Pro" to our new unified "Easing Slider" customizer extension.
12
- *
13
- * Lots of horrible, messy legacy code here that I absolutely hate, but is necessary.
14
- *
15
- * @uses ES_Slider
16
- * @author Matthew Ruddy
17
- */
18
- class ES_Customizer_Legacy {
19
-
20
- /**
21
- * Gets a Easing Slider "Pro" legacy slider.
22
- *
23
- * @param int $legacy_id The legacy slider ID
24
- * @return ES_Slider|false
25
- */
26
- public function get_pro_slider( $legacy_id ) {
27
-
28
- // Bail if Easing Slider isn't active
29
- if ( ! class_exists( 'ES_Slider' ) ) {
30
- return false;
31
- }
32
-
33
- // Get our "pivot" array option
34
- $pivots = get_option( 'easingslider_pro_slider_pivots' );
35
-
36
- // Bail if we have no pivots
37
- if ( ! $pivots ) {
38
- return false;
39
- }
40
-
41
- // Loop through each pivot and return the match, if we have find one.
42
- foreach ( $pivots as $pivot ) {
43
- if ( $legacy_id == $pivot->legacy_id ) {
44
- return ES_Slider::find( $pivot->id );
45
- }
46
- }
47
-
48
- return false;
49
-
50
- }
51
-
52
- /**
53
- * Upgrades the plugin from Easing Slider "Pro" v2.0 and onwards.
54
- *
55
- * @return void
56
- */
57
- public function pro_upgrade_from_200() {
58
-
59
- global $wpdb;
60
-
61
- // Bail if this has already been carried out
62
- if ( get_option( 'easingslider-customizer_upgraded_from_pro' ) ) {
63
- return;
64
- }
65
-
66
- // Bail if we don't have a version, telling us that the plugin wasn't installed and there is nothing to upgrade.
67
- if ( ! get_option( 'easingsliderpro_version' ) ) {
68
- return;
69
- }
70
-
71
- // Get the legacy sliders
72
- $legacy_sliders = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}easingsliderpro" );
73
-
74
- // Add the sliders, if we have any.
75
- if ( $legacy_sliders ) {
76
- foreach ( $legacy_sliders as $legacy_slider ) {
77
-
78
- // Get the Easing Slider "Pro" slider
79
- $slider = $this->get_pro_slider( $legacy_slider->id, $legacy_slider->name );
80
-
81
- // Bail if we have no slider
82
- if ( ! $slider ) {
83
- return false;
84
- }
85
-
86
- // Add customizations if we have any
87
- if ( ! empty( $legacy_slider->customizations ) ) {
88
-
89
- // Decode the legacy slider's json
90
- $legacy_slider->customizations = json_decode( $legacy_slider->customizations );
91
-
92
- // Transfer the data
93
- $slider->customizations = $legacy_slider->customizations;
94
-
95
- // Make some ammendments to our properties (fixing some inconsistencies and mapping new images)
96
- $slider->customizations->shadow->enabled = $slider->customizations->shadow->enable;
97
- $slider->customizations->shadow->image = str_replace( 'easingsliderpro/images/slideshow_shadow.png', 'easing-slider/images/shadow.png', $slider->customizations->shadow->image );
98
- $slider->customizations->arrows->next = str_replace( 'easingsliderpro/images/slideshow_arrow_next.png', 'easing-slider/images/nav-arrow-next.png', $slider->customizations->arrows->next );
99
- $slider->customizations->arrows->prev = str_replace( 'easingsliderpro/images/slideshow_arrow_prev.png', 'easing-slider/images/nav-arrow-prev.png', $slider->customizations->arrows->prev );
100
- $slider->customizations->pagination->active = str_replace( 'easingsliderpro/images/slideshow_icon_active.png', 'easing-slider/images/nav-icon-active.png', $slider->customizations->pagination->active );
101
- $slider->customizations->pagination->inactive = str_replace( 'easingsliderpro/images/slideshow_icon_inactive.png', 'easing-slider/images/nav-icon-inactive.png', $slider->customizations->pagination->inactive );
102
-
103
- // Remove properties that are no longer used
104
- unset( $slider->customizations->shadow->enable );
105
-
106
- }
107
-
108
- // Save the slider
109
- $slider->save();
110
-
111
- }
112
- }
113
-
114
- // Flag that this upgrade has been done
115
- update_option( 'easingslider-customizer_upgraded_from_pro', true );
116
-
117
- }
118
-
119
- /**
120
- * Gets the Easing Slider "Lite" legacy slider.
121
- *
122
- * @return ES_Slider|false
123
- */
124
- public function get_lite_slider() {
125
-
126
- // Bail if Easing Slider isn't active
127
- if ( ! class_exists( 'ES_Slider' ) ) {
128
- return false;
129
- }
130
-
131
- // Get the ID of our "Lite" slider
132
- $lite_id = get_option( 'easingslider_lite_slider_id' );
133
-
134
- // Get the Easing Slider "Lite" slider
135
- $lite_slider = ES_Slider::find( $lite_id );
136
-
137
- return $lite_slider;
138
-
139
- }
140
-
141
- /**
142
- * Upgrades the plugin from Easing Slider "Lite" v1.0 and onwards.
143
- *
144
- * @return void
145
- */
146
- public function lite_upgrade_from_100() {
147
-
148
- // Bail if this has already been carried out
149
- if ( get_option( 'easingslider-customizer_upgraded_from_lite' ) ) {
150
- return;
151
- }
152
-
153
- /**
154
- * This version of the plugin had no "version" option, so we have to improvise.
155
- *
156
- * To do this, we will cycle through the options used to store the images from #1 to #10.
157
- * If we find an image, we will assume the plugin settings exist and will continue with the upgrade.
158
- */
159
- $legacy_images = array( 'sImg1', 'sImg2', 'sImg3', 'sImg4', 'sImg5', 'sImg6', 'sImg7', 'sImg8', 'sImg9', 'sImg10' );
160
-
161
- // Loop through each image option, and continue if we find a match.
162
- foreach ( $legacy_images as $legacy_image ) {
163
-
164
- // Continue if we find an image, telling us that the plugin was being used
165
- if ( get_option( $legacy_image ) ) {
166
-
167
- // Get the Easing Slider "Lite" slider
168
- $slider = $this->get_lite_slider();
169
-
170
- // Enable shadow
171
- $slider->customizations->shadow->enabled = true;
172
-
173
- // Save the slider
174
- $slider->save();
175
-
176
- // Flag that this upgrade has been done
177
- update_option( 'easingslider-customizer_upgraded_from_lite', true );
178
-
179
- // We've done our update. Time to bail!
180
- return;
181
-
182
- }
183
-
184
- }
185
-
186
- }
187
-
188
- /**
189
- * Upgrades the plugin from Easing Slider "Lite" v2.0 and onwards.
190
- *
191
- * @return void
192
- */
193
- public function lite_upgrade_from_200() {
194
-
195
- global $wpdb;
196
-
197
- // Bail if this has already been carried out
198
- if ( get_option( 'easingslider-customizer_upgraded_from_lite' ) ) {
199
- return;
200
- }
201
-
202
- /**
203
- * In my previous attempts to change the plugin name from "Easing Slider" to "Riva Slider",
204
- * I made the catastrophic mistake of changing the plugin directory name and options, etc, which
205
- * created dozens of issues and prompted the name change reversal.
206
- *
207
- * As a result, it's possible options may exist under the prefix "rivaslider" or "easingslider".
208
- * Let's accommodate for both.
209
- */
210
- $plugin_slug = ( get_option( 'easingsliderlite_version' ) ) ? 'easingsliderlite' : 'rivasliderlite';
211
-
212
- // Get the legacy slider customizations
213
- $legacy_customizations = get_option( "{$plugin_slug}_customizations" );
214
-
215
- // Bail if we have no customizations
216
- if ( ! $legacy_customizations ) {
217
- return;
218
- }
219
-
220
- // Get the Easing Slider "Lite" slider
221
- $slider = $this->get_lite_slider();
222
-
223
- // Bail if we have no slider
224
- if ( ! $slider ) {
225
- return false;
226
- }
227
-
228
- // Transfer the data
229
- $slider->customizations = $legacy_customizations;
230
-
231
- // Make some ammendments to our properties (fixing some inconsistencies and mapping new images)
232
- $slider->customizations->shadow->enabled = $slider->customizations->shadow->enable;
233
- $slider->customizations->shadow->image = str_replace( 'images/slideshow_shadow.png', 'images/shadow.png', $slider->customizations->shadow->image );
234
- $slider->customizations->arrows->next = str_replace( 'images/slideshow_arrow_next.png', 'images/nav-arrow-next.png', $slider->customizations->arrows->next );
235
- $slider->customizations->arrows->prev = str_replace( 'images/slideshow_arrow_prev.png', 'images/nav-arrow-prev.png', $slider->customizations->arrows->prev );
236
- $slider->customizations->pagination->active = str_replace( 'images/slideshow_icon_active.png', 'images/nav-icon-active.png', $slider->customizations->pagination->active );
237
- $slider->customizations->pagination->inactive = str_replace( 'images/slideshow_icon_inactive.png', 'images/nav-icon-inactive.png', $slider->customizations->pagination->inactive );
238
-
239
- // Remove properties that are no longer used
240
- unset( $slider->customizations->shadow->enable );
241
-
242
- // Save the slider
243
- $slider->save();
244
-
245
- // Flag that this upgrade has been done
246
- update_option( 'easingslider-customizer_upgraded_from_lite', true );
247
-
248
- }
249
-
250
- /**
251
- * Deletes all the legacy related options.
252
- *
253
- * @return void
254
- */
255
- public function remove_options() {
256
-
257
- delete_option( 'easingslider-customizer_upgraded_from_lite' );
258
- delete_option( 'easingslider-customizer_upgraded_from_pro' );
259
-
260
- }
261
-
262
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-customizer-notice.php DELETED
@@ -1,86 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * This class adds a notice to the WordPress admin area telling users that the
12
- * "Customizer" functionality will soon be extracted into a separate extension.
13
- *
14
- * @author Matthew Ruddy
15
- */
16
- class ES_Customizer_Notice {
17
-
18
- /**
19
- * Sets the database "flag" option for this notice
20
- *
21
- * @return void
22
- */
23
- public function set_flag() {
24
-
25
- add_option( 'easingslider_dismissed_customizer_notice', true );
26
-
27
- }
28
-
29
- /**
30
- * Deletes the database "flag" option for this notice
31
- *
32
- * @return void
33
- */
34
- public function unset_flag() {
35
-
36
- delete_option( 'easingslider_dismissed_customizer_notice' );
37
-
38
- }
39
-
40
- /**
41
- * Dismisses the notice, if applicable
42
- *
43
- * @return void
44
- */
45
- public function handle_dismiss() {
46
-
47
- // Check for dismissal
48
- if ( ! empty( $_GET['dismiss_customizer_notice'] ) ) {
49
-
50
- // Set the flag, telling us that the user has dismissed the notice
51
- $this->set_flag();
52
-
53
- }
54
-
55
- }
56
-
57
- /**
58
- * Displays the notice
59
- *
60
- * @return void
61
- */
62
- public function display() {
63
-
64
- // Bail if not an plugin admin page
65
- if ( ! isset( $_GET['page'] ) ) {
66
- return;
67
- }
68
-
69
- // Get the current page URL
70
- $current_page = "{$_SERVER['REQUEST_URI']}&amp;dismiss_customizer_notice=true";
71
-
72
- // Populate the message
73
- $message = sprintf( __( 'The Easing Slider "Customizer" functionality will soon be removed from this plugin and made available as an extension. If you use the "Customize" panel, download and activate the free extension <a href="%s" target="_blank">here</a> to prevents any disruptions. <a href="%s">Dismiss</a>.', 'easingslider' ), 'http://easingslider.com/extensions/visual-customizer', $current_page );
74
-
75
- // Bail if we've dismissed the notice
76
- if ( get_option( 'easingslider_dismissed_customizer_notice' ) ) {
77
- return;
78
- }
79
-
80
- // Tell the user
81
- if ( function_exists( 'easingslider_show_notice' ) ) {
82
- easingslider_show_notice( $message, 'updated notice' );
83
- }
84
-
85
- }
86
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-customizer.php DELETED
@@ -1,231 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Defines our "Customizer"
12
- *
13
- * @uses ES_Slider
14
- * @uses Easing_Slider
15
- * @author Matthew Ruddy
16
- */
17
- class ES_Customizer {
18
-
19
- /**
20
- * Adds our "customizer" user capabilities
21
- *
22
- * @return void
23
- */
24
- public function add_capabilities() {
25
-
26
- // Get user role
27
- $role = get_role( 'administrator' );
28
-
29
- // Add the capability
30
- $role->add_cap( 'easingslider_manage_customizations' );
31
-
32
- }
33
-
34
- /**
35
- * Removes our "customizer" user capabilities
36
- *
37
- * @return void
38
- */
39
- public function remove_capabilities() {
40
-
41
- // Get user role
42
- $role = get_role( 'administrator' );
43
-
44
- // Remove the capability
45
- $role->remove_cap( 'easingslider_manage_customizations' );
46
-
47
- }
48
-
49
-
50
- /**
51
- * Adds our page to the "Sliders" menu
52
- *
53
- * @return void
54
- */
55
- public function add_submenu_page() {
56
-
57
- // "Customize" page
58
- $hook = add_submenu_page(
59
- 'easingslider_edit_sliders',
60
- __( 'Customize', 'easingslider' ),
61
- __( 'Customize', 'easingslider' ),
62
- 'easingslider_manage_customizations',
63
- 'easingslider_manage_customizations',
64
- array( $this, 'display_view' )
65
- );
66
-
67
- // Page-specific hooks
68
- add_action( "load-{$hook}", array( $this, 'do_actions' ) );
69
- add_action( "admin_print_styles-{$hook}", array( $this, 'enqueue_styles' ) );
70
- add_action( "admin_print_scripts-{$hook}", array( $this, 'enqueue_scripts' ) );
71
-
72
- }
73
-
74
- /**
75
- * Registers our assets
76
- *
77
- * @return void
78
- */
79
- public function register_assets() {
80
-
81
- // Get our directories
82
- $css_dir = plugin_dir_url( Easing_Slider::$file ) . 'css';
83
- $js_dir = plugin_dir_url( Easing_Slider::$file ) . 'js';
84
-
85
- // Get file suffix
86
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
87
-
88
- // Dependancies
89
- $dependancies = array( 'jquery', 'backbone' );
90
-
91
- // Register our stylesheets
92
- wp_register_style( 'easingslider-customizer', "{$css_dir}/customizer{$suffix}.css", false, Easing_Slider::$version );
93
-
94
- // Register our javascripts
95
- wp_register_script( 'easingslider-customizer', "{$js_dir}/customizer{$suffix}.js", $dependancies, Easing_Slider::$version, true );
96
-
97
- }
98
-
99
- /**
100
- * Enqueues all of our customizer styles
101
- *
102
- * @return void
103
- */
104
- public function enqueue_styles() {
105
-
106
- // Enqueue our stylesheets
107
- wp_enqueue_style( 'customize-controls' );
108
- wp_enqueue_style( 'wp-color-picker' );
109
- wp_enqueue_style( 'easingslider' );
110
- wp_enqueue_style( 'easingslider-customizer' );
111
-
112
- }
113
-
114
- /**
115
- * Enqueues all of our customizer scripts
116
- *
117
- * @return void
118
- */
119
- public function enqueue_scripts() {
120
-
121
- // Enqueue our javascripts
122
- wp_enqueue_script( 'customize-controls');
123
- wp_enqueue_script( 'wp-color-picker' );
124
- wp_enqueue_script( 'easingslider' );
125
- wp_enqueue_script( 'easingslider-customizer' );
126
-
127
- }
128
-
129
- /**
130
- * Gets the "customizer" form fields
131
- *
132
- * @return array
133
- */
134
- public function get_form_fields() {
135
-
136
- $data = apply_filters( 'easingslider-customizer_form_fields', array() );
137
-
138
- // Form fields
139
- $fields = array( 'arrows', 'pagination', 'border', 'shadow' );
140
-
141
- // Set form fields
142
- foreach ( $fields as $field ) {
143
- if ( isset( $_POST[ $field ] ) ) {
144
- $data[ $field ] = (object) $_POST[ $field ];
145
- }
146
- }
147
-
148
- // If data validation functionality exists, use it.
149
- if ( function_exists( 'easingslider_validate_data' ) ) {
150
- foreach ( $data as &$value ) {
151
- $value = easingslider_validate_data( $value );
152
- }
153
- }
154
-
155
- return $data;
156
-
157
- }
158
-
159
- /**
160
- * Does our "customizer" actions
161
- *
162
- * @return void
163
- */
164
- public function do_actions() {
165
-
166
- // Bail if not on the customizer page
167
- if ( isset( $_POST['save'] ) && isset( $_POST['slider_id'] ) ) {
168
-
169
- // Get our slider
170
- $slider = ES_Slider::find( $_POST['slider_id'] );
171
-
172
- // Set the customizations
173
- $slider->customizations = (object) $this->get_form_fields();
174
-
175
- // Save the slider
176
- $slider->save();
177
-
178
- // Redirect back to the customizer
179
- wp_redirect( "admin.php?page=easingslider_manage_customizations&edit={$slider->ID}" );
180
-
181
- }
182
-
183
- }
184
-
185
- /**
186
- * Displays the view
187
- *
188
- * @return void
189
- */
190
- public function display_view() {
191
-
192
- // Get the current page
193
- $page = sanitize_key( $_GET['page'] );
194
-
195
- // We need Easing Slider to be loaded by now, so continue if it has.
196
- if ( class_exists( 'ES_Slider' ) ) {
197
-
198
- // Get all sliders
199
- $sliders = ES_Slider::all();
200
-
201
- // If we have no sliders, tell the user.
202
- if ( empty( $sliders ) ) {
203
- wp_die( __( 'You need to create some sliders to use the customizer.', 'easingslider' ) );
204
- exit();
205
- }
206
-
207
- // Get the specified slider, or pick the first one.
208
- if ( isset( $_GET['edit'] ) ) {
209
-
210
- // Get and validate the ID, protecting against XSS attacks
211
- $id = sanitize_key( $_GET['edit'] );
212
-
213
- // Get the slider
214
- $slider = ES_Slider::find( $id );
215
-
216
- }
217
- else {
218
-
219
- // Get the first slider
220
- $slider = array_shift( array_values( $sliders ) );
221
-
222
- }
223
-
224
- // Display the view
225
- require plugin_dir_path( dirname( __FILE__ ) ) . 'partials/customizer.php';
226
-
227
- }
228
-
229
- }
230
-
231
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-editor-pages.php DELETED
@@ -1,414 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Defines our admin slider editor pages.
12
- *
13
- * @uses ES_Slider
14
- * @uses ES_Sliders_List_Table
15
- * @uses Easing_Slider
16
- * @author Matthew Ruddy
17
- */
18
- class ES_Editor_Pages {
19
-
20
- /**
21
- * Adds our editor user capabilities
22
- *
23
- * @return void
24
- */
25
- public function add_capabilities() {
26
-
27
- // Get user role
28
- $role = get_role( 'administrator' );
29
-
30
- // Add the capabilities
31
- $role->add_cap( 'easingslider_edit_sliders' );
32
- $role->add_cap( 'easingslider_publish_sliders' );
33
-
34
- }
35
-
36
- /**
37
- * Removes our editor user capabilities
38
- *
39
- * @return void
40
- */
41
- public function remove_capabilities() {
42
-
43
- // Get user role
44
- $role = get_role( 'administrator' );
45
-
46
- // Remove the capabilities
47
- $role->remove_cap( 'easingslider_edit_sliders' );
48
- $role->remove_cap( 'easingslider_publish_sliders' );
49
-
50
- }
51
-
52
- /**
53
- * Adds our "All Sliders" page to the plugin admin menu
54
- *
55
- * @return void
56
- */
57
- public function add_edit_page() {
58
-
59
- // "All Sliders" page
60
- $hook = add_submenu_page(
61
- 'easingslider_edit_sliders',
62
- __( 'Sliders', 'easingslider' ),
63
- __( 'All Sliders', 'easingslider' ),
64
- 'easingslider_edit_sliders',
65
- 'easingslider_edit_sliders',
66
- array( $this, 'display_edit_view' )
67
- );
68
-
69
- // Page-specific hooks
70
- add_action( "load-{$hook}", array( $this, 'do_edit_actions' ) );
71
- add_action( "load-{$hook}", array( $this, 'add_screen_options' ) );
72
- add_action( "load-{$hook}", array( $this, 'hide_media_tabs' ) );
73
- add_action( "admin_print_styles-{$hook}", array( $this, 'enqueue_styles' ) );
74
- add_action( "admin_print_scripts-{$hook}", array( $this, 'enqueue_scripts' ) );
75
-
76
- }
77
-
78
- /**
79
- * Adds our "Add New" page to the plugin admin menu
80
- *
81
- * @return void
82
- */
83
- public function add_publish_page() {
84
-
85
- // "Add New" page
86
- $hook = add_submenu_page(
87
- 'easingslider_edit_sliders',
88
- __( 'Add New Slider', 'easingslider' ),
89
- __( 'Add New', 'easingslider' ),
90
- 'easingslider_publish_sliders',
91
- 'easingslider_publish_slider',
92
- array( $this, 'display_publish_view' )
93
- );
94
-
95
- // Page-specific hooks
96
- add_action( "load-{$hook}", array( $this, 'do_publish_actions' ) );
97
- add_action( "load-{$hook}", array( $this, 'add_screen_options' ) );
98
- add_action( "load-{$hook}", array( $this, 'hide_media_tabs' ) );
99
- add_action( "admin_print_styles-{$hook}", array( $this, 'enqueue_styles' ) );
100
- add_action( "admin_print_scripts-{$hook}", array( $this, 'enqueue_scripts' ) );
101
-
102
- }
103
-
104
- /**
105
- * Registers all of our editor assets
106
- *
107
- * @return void
108
- */
109
- public function register_assets() {
110
-
111
- // Get our directories
112
- $css_dir = plugin_dir_url( Easing_Slider::$file ) . 'css';
113
- $js_dir = plugin_dir_url( Easing_Slider::$file ) . 'js';
114
-
115
- // Get file suffix
116
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
117
-
118
- // Dependancies
119
- $dependancies = array( 'jquery', 'jquery-ui-sortable', 'backbone', 'media-grid' );
120
-
121
- // Register our stylesheets
122
- wp_register_style( 'easingslider-editor-pages', "{$css_dir}/editor-pages{$suffix}.css", false, Easing_Slider::$version );
123
-
124
- // Register our javascripts
125
- wp_register_script( 'easingslider-editor-pages', "{$js_dir}/editor-pages{$suffix}.js", $dependancies, Easing_Slider::$version, true );
126
-
127
- }
128
-
129
- /**
130
- * Enqueues all of our editor styles
131
- *
132
- * @return void
133
- */
134
- public function enqueue_styles() {
135
-
136
- // Enqueue our stylesheets
137
- wp_enqueue_style( 'easingslider-editor-pages' );
138
-
139
- }
140
-
141
- /**
142
- * Enqueues all of our editor scripts
143
- *
144
- * @return void
145
- */
146
- public function enqueue_scripts() {
147
-
148
- // Load media grid localizations
149
- wp_localize_script( 'media-grid', '_wpMediaGridSettings', array(
150
- 'adminUrl' => parse_url( self_admin_url(), PHP_URL_PATH ),
151
- ) );
152
-
153
- // Load our localizations
154
- wp_localize_script( 'easingslider-editor-pages', '_easingsliderEditorL10n', array(
155
- 'warn' => __( 'Are you sure you wish to do this? This cannot be reversed.', 'easingslider' ),
156
- 'plugin_url' => '/wp-content/plugins/'. dirname( plugin_basename( __FILE__ ) ) .'/',
157
- 'delete_slide' => __( 'Are you sure you wish to delete this slide? This cannot be reversed.', 'easingslider' ),
158
- 'delete_slides' => __( 'Are you sure you wish to delete all of this slider\'s images? This cannot be reversed.', 'easingslider' ),
159
- 'media_upload' => array(
160
- 'title' => __( 'Edit Slide', 'easingslider' ),
161
- 'update' => __( 'Update', 'easingslider' ),
162
- 'image_from_media' => __( 'Image from Media', 'easingslider' ),
163
- 'insert_into_slider' => __( 'Insert into Slider', 'easingslider' )
164
- )
165
- ) );
166
-
167
- // Enqueue our javascripts
168
- wp_enqueue_media();
169
- wp_enqueue_script( 'easingslider-editor-pages' );
170
-
171
- // Print our backbone templates
172
- add_action( 'admin_footer', array( $this, 'print_backbone_templates' ) );
173
-
174
- }
175
-
176
- /**
177
- * Adds our editor screen options
178
- *
179
- * @return void
180
- */
181
- public function add_screen_options() {
182
-
183
- // Show the appropriate screen options
184
- if ( ! isset( $_GET['edit'] ) ) {
185
-
186
- /**
187
- * WP_List_Table automatically adds the table columns to our screen options when initialised,
188
- * so let's trigger this by creating a new instance of our class.
189
- */
190
- $list_table = new ES_Sliders_List_Table();
191
-
192
- // Add the sliders per page screen option
193
- add_screen_option( 'per_page', array(
194
- 'label' => __( 'Sliders per page', 'easingslider' ),
195
- 'default' => 20,
196
- 'option' => 'sliders_per_page'
197
- ) );
198
-
199
- }
200
-
201
- }
202
-
203
- /**
204
- * Sets our editor screen option
205
- *
206
- * @param mixed $status
207
- * @param mixed $option The screen option
208
- * @param mixed $value The screen option value
209
- * @return mixed
210
- */
211
- public function set_screen_option( $status, $option, $value ) {
212
-
213
- if ( 'sliders_per_page' == $option ) {
214
- return $value;
215
- }
216
-
217
- }
218
-
219
- /**
220
- * Hides any Media Upload (possibly from other plugins) that we don't want to show
221
- *
222
- * @return void
223
- */
224
- public function hide_media_tabs() {
225
-
226
- add_filter( 'media_upload_tabs', '__return_empty_array', 99999 );
227
-
228
- }
229
-
230
- /**
231
- * Prints our backbone.js templates
232
- *
233
- * @return void
234
- */
235
- public function print_backbone_templates() {
236
-
237
- // Require our templates
238
- require plugin_dir_path( dirname( __FILE__ ) ) . 'backbone/edit-slide.php';
239
- require plugin_dir_path( dirname( __FILE__ ) ) . 'backbone/slide.php';
240
-
241
- }
242
-
243
- /**
244
- * Gets our form fields
245
- *
246
- * @return array
247
- */
248
- public function get_form_fields() {
249
-
250
- $data = apply_filters( 'easingslider_pre_get_editor_form_fields', array() );
251
-
252
- // Set the form fields
253
- if ( isset( $_POST['post_title'] ) ) {
254
- $data['post_title'] = $_POST['post_title'];
255
- }
256
- if ( isset( $_POST['general'] ) ) {
257
- $data['general'] = (object) easingslider_validate_data( $_POST['general'] );
258
- }
259
- if ( isset( $_POST['dimensions'] ) ) {
260
- $data['dimensions'] = (object) easingslider_validate_data( $_POST['dimensions'] );
261
- }
262
- if ( isset( $_POST['transitions'] ) ) {
263
- $data['transitions'] = (object) easingslider_validate_data( $_POST['transitions'] );
264
- }
265
- if ( isset( $_POST['navigation'] ) ) {
266
- $data['navigation'] = (object) easingslider_validate_data( $_POST['navigation'] );
267
- }
268
- if ( isset( $_POST['playback'] ) ) {
269
- $data['playback'] = (object) easingslider_validate_data( $_POST['playback'] );
270
- }
271
- if ( isset( $_POST['slides'] ) ) {
272
- $data['slides'] = array_map( 'easingslider_validate_data', $_POST['slides'] );
273
-
274
- $data['slides'] = array_map( 'json_decode', $data['slides'] );
275
- }
276
- else {
277
- $data['slides'] = array();
278
- }
279
-
280
- return $data;
281
-
282
- }
283
-
284
- /**
285
- * Does our edit actions
286
- *
287
- * @return void
288
- */
289
- public function do_edit_actions() {
290
-
291
- // Continue if the save button has been pressed
292
- if ( isset( $_POST['save'] ) && isset( $_GET['edit'] ) ) {
293
-
294
- // Bail if nonce is invalid
295
- if ( ! check_admin_referer( 'save' ) ) {
296
- return;
297
- }
298
-
299
- // Get and validate the ID, protecting against XSS attacks
300
- $id = sanitize_key( $_GET['edit'] );
301
-
302
- // Get our slider
303
- $slider = ES_Slider::find( $id );
304
-
305
- // Update attributes
306
- $slider->set( $this->get_form_fields() );
307
-
308
- // Save the slider
309
- $slider->save();
310
-
311
- // Trigger actions
312
- do_action( 'easingslider_save_slider_actions', $slider );
313
-
314
- // Tell the user
315
- easingslider_show_notice( __( 'Slider has been saved successfully.', 'easingslider' ), 'updated' );
316
-
317
- }
318
-
319
- // Trigger actions
320
- do_action( 'easingslider_do_editor_actions' );
321
-
322
- }
323
-
324
- /**
325
- * Does our publish actions
326
- *
327
- * @return void
328
- */
329
- public function do_publish_actions() {
330
-
331
- // Continue if the save button has been pressed
332
- if ( isset( $_POST['save'] ) ) {
333
-
334
- // Bail if nonce is invalid
335
- if ( ! check_admin_referer( 'save' ) ) {
336
- return;
337
- }
338
-
339
- // Create a new slider
340
- $slider = ES_Slider::create();
341
-
342
- // Set attributes
343
- $slider->set( $this->get_form_fields() );
344
-
345
- // Save the slider
346
- $slider->save();
347
-
348
- // Trigger actions
349
- do_action( 'easingslider_publish_slider_actions', $slider );
350
-
351
- // Redirect to the editor for our new slider
352
- wp_redirect( "admin.php?page=easingslider_edit_sliders&edit={$slider->ID}" );
353
-
354
- }
355
-
356
- // Trigger actions
357
- do_action( 'easingslider_do_editor_actions' );
358
-
359
- }
360
-
361
- /**
362
- * Displays the edit view
363
- *
364
- * @return void
365
- */
366
- public function display_edit_view() {
367
-
368
- // Get the page
369
- $page = sanitize_key( $_GET['page'] );
370
-
371
- // Show the appropriate view
372
- if ( isset( $_GET['edit'] ) ) {
373
-
374
- // Get and validate the ID, protecting against XSS attacks
375
- $id = sanitize_key( $_GET['edit'] );
376
-
377
- // Get the slider by its ID
378
- $slider = ES_Slider::find( $id );
379
-
380
- // Display the editor
381
- require plugin_dir_path( dirname( __FILE__ ) ) . 'partials/edit-slider.php';
382
-
383
- }
384
- else {
385
-
386
- // Get the sliders list table
387
- $list_table = new ES_Sliders_List_Table();
388
-
389
- // Display the list
390
- require plugin_dir_path( dirname( __FILE__ ) ) . 'partials/list-sliders.php';
391
-
392
- }
393
-
394
- }
395
-
396
- /**
397
- * Displays the publish view
398
- *
399
- * @return void
400
- */
401
- public function display_publish_view() {
402
-
403
- // Get the current page
404
- $page = sanitize_key( $_GET['page'] );
405
-
406
- // Initiate a new slider
407
- $slider = ES_Slider::create();
408
-
409
- // Display the view
410
- require plugin_dir_path( dirname( __FILE__ ) ) . 'partials/edit-slider.php';
411
-
412
- }
413
-
414
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-extensions-page.php DELETED
@@ -1,156 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * This code is for debugging purposes.
12
- * Uncomment this line to force Easing Slider to fetch the available extensions
13
- */
14
- // delete_transient( 'easingslider_available_extensions' );
15
-
16
- /**
17
- * Class for "Extensions" discovery page.
18
- *
19
- * @uses Easing_Slider
20
- * @author Matthew Ruddy
21
- */
22
- class ES_Extensions_Page {
23
-
24
- /**
25
- * Adds our "extensions" page user capabilities
26
- *
27
- * @return void
28
- */
29
- public function add_capabilities() {
30
-
31
- // Get user role
32
- $role = get_role( 'administrator' );
33
-
34
- // Add the capability
35
- $role->add_cap( 'easingslider_discover_extensions' );
36
-
37
- }
38
-
39
- /**
40
- * Removes our "extensions" page user capabilities
41
- *
42
- * @return void
43
- */
44
- public function remove_capabilities() {
45
-
46
- // Get user role
47
- $role = get_role( 'administrator' );
48
-
49
- // Remove the capability
50
- $role->remove_cap( 'easingslider_discover_extensions' );
51
-
52
- }
53
-
54
- /**
55
- * Adds our page to the "Sliders" menu
56
- *
57
- * @return void
58
- */
59
- public function add_submenu_page() {
60
-
61
- // "Extensions" page
62
- $hook = add_submenu_page(
63
- 'easingslider_edit_sliders',
64
- __( 'Extensions', 'easingslider' ),
65
- __( 'Extensions', 'easingslider' ),
66
- 'easingslider_discover_extensions',
67
- 'easingslider_discover_extensions',
68
- array( $this, 'display_view' )
69
- );
70
-
71
- // Page-specific hooks
72
- add_action( "admin_print_styles-{$hook}", array( $this, 'enqueue_styles' ) );
73
-
74
- }
75
-
76
- /**
77
- * Registers all of our extensions page assets
78
- *
79
- * @return void
80
- */
81
- public function register_assets() {
82
-
83
- // Get our directory
84
- $css_dir = plugin_dir_url( Easing_Slider::$file ) . 'css';
85
-
86
- // Get file suffix
87
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
88
-
89
- // Register our stylesheet
90
- wp_register_style( 'easingslider-extensions-page', "{$css_dir}/extensions-page{$suffix}.css", false, Easing_Slider::$version );
91
-
92
- }
93
-
94
- /**
95
- * Enqueues all of our extensions page styles
96
- *
97
- * @return void
98
- */
99
- public function enqueue_styles() {
100
-
101
- // Enqueue our stylesheet
102
- wp_enqueue_style( 'easingslider-extensions-page' );
103
-
104
- }
105
-
106
- /**
107
- * Returns an array of available extensions
108
- *
109
- * @return false|array
110
- */
111
- public function available_extensions() {
112
-
113
- // Get the cached extensions feed. If it has expired, fetch it again.
114
- if ( false === ( $available_extensions = get_transient( 'easingslider_available_extensions' ) ) ) {
115
-
116
- // Fetch the feed
117
- $request = wp_remote_get( 'http://easingslider.com/?feed=extensions' );
118
-
119
- // Return false if we encounter an error
120
- if ( is_wp_error( $request ) ) {
121
- return false;
122
- }
123
-
124
- // Check for response body
125
- if ( ! isset( $request['body'] ) ) {
126
- return false;
127
- }
128
-
129
- // Get available extensions
130
- $available_extensions = json_decode( $request['body'] );
131
-
132
- // Cache response
133
- set_transient( 'easingslider_available_extensions', $available_extensions, 3600 );
134
-
135
- }
136
-
137
- return $available_extensions;
138
-
139
- }
140
-
141
- /**
142
- * Displays the view
143
- *
144
- * @return void
145
- */
146
- public function display_view() {
147
-
148
- // Get available extensions
149
- $extensions = $this->available_extensions();
150
-
151
- // Display the view
152
- require plugin_dir_path( dirname( __FILE__ ) ) . 'partials/discover-extensions.php';
153
-
154
- }
155
-
156
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-image-resizer.php DELETED
@@ -1,234 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Our custom image resizing class (no Timthumb here!)
12
- *
13
- * @author Matthew Ruddy
14
- */
15
- class ES_Image_Resizer {
16
-
17
- /**
18
- * Resizes an image
19
- *
20
- * @param string $url The image URL
21
- * @param int $width The desired width
22
- * @param int $height The desired height
23
- * @param boolean $crop Toggles cropping
24
- * @param int $quality The resized image quality
25
- * @return array|WP_Error
26
- */
27
- public function resize( $url, $width, $height, $crop = true, $quality = 100 ) {
28
-
29
- global $wpdb;
30
-
31
- // Return a WP_Error if an empty URL was provided
32
- if ( empty( $url ) ) {
33
- return new WP_Error( 'no_image_url', __( 'No image URL has been entered.', 'easingslider' ), $url );
34
- }
35
-
36
- /**
37
- * Bail if this image isn't in the Media Library.
38
- *
39
- * We only want to resize Media Library images, so we can be sure they get deleted correctly when appropriate.
40
- */
41
- $query = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE guid='%s'", $url );
42
- $get_attachment = $wpdb->get_results( $query );
43
-
44
- if ( ! $get_attachment ) {
45
- return array( 'url' => $url, 'width' => $width, 'height' => $height );
46
- }
47
-
48
- // Get the image file path
49
- $file_path = parse_url( $url );
50
- $file_path = $_SERVER['DOCUMENT_ROOT'] . $file_path['path'];
51
-
52
- // Additional handling for multisite
53
- if ( is_multisite() ) {
54
- global $blog_id;
55
- $blog_details = get_blog_details( $blog_id );
56
- $file_path = str_replace( $blog_details->path . 'files/', '/wp-content/blogs.dir/'. $blog_id .'/files/', $file_path );
57
- }
58
-
59
- // Destination width and height variables
60
- $dest_width = apply_filters( 'easingslider_resize_image_width', $width, $get_attachment );
61
- $dest_height = apply_filters( 'easingslider_resize_image_height', $height, $get_attachment );
62
-
63
- // File name suffix (appended to original file name)
64
- $suffix = "{$dest_width}x{$dest_height}";
65
-
66
- // Some additional info about the image
67
- $info = pathinfo( $file_path );
68
- $dir = $info['dirname'];
69
- $ext = $info['extension'];
70
- $name = wp_basename( $file_path, ".$ext" );
71
-
72
- // Suffix applied to filename
73
- $suffix = "{$dest_width}x{$dest_height}";
74
-
75
- // Get the destination file name
76
- $dest_file_name = "{$dir}/{$name}-{$suffix}.{$ext}";
77
-
78
- // Execute the resizing if resized image doesn't already exist.
79
- if ( ! file_exists( $dest_file_name ) ) {
80
-
81
- // Load Wordpress Image Editor
82
- $editor = wp_get_image_editor( $file_path );
83
-
84
- // Bail if we encounter a WP_Error
85
- if ( is_wp_error( $editor ) ) {
86
- return array( 'url' => $url, 'width' => $width, 'height' => $height );
87
- }
88
-
89
- // Set the quality
90
- $editor->set_quality( $quality );
91
-
92
- // Get the original image size
93
- $size = $editor->get_size();
94
- $orig_width = $size['width'];
95
- $orig_height = $size['height'];
96
-
97
- $src_x = $src_y = 0;
98
- $src_w = $orig_width;
99
- $src_h = $orig_height;
100
-
101
- // Handle cropping
102
- if ( $crop ) {
103
-
104
- $cmp_x = $orig_width / $dest_width;
105
- $cmp_y = $orig_height / $dest_height;
106
-
107
- // Calculate x or y coordinate, and width or height of source
108
- if ( $cmp_x > $cmp_y ) {
109
- $src_w = round( $orig_width / $cmp_x * $cmp_y );
110
- $src_x = round( ( $orig_width - ( $orig_width / $cmp_x * $cmp_y ) ) / 2 );
111
- }
112
- else if ( $cmp_y > $cmp_x ) {
113
- $src_h = round( $orig_height / $cmp_y * $cmp_x );
114
- $src_y = round( ( $orig_height - ( $orig_height / $cmp_y * $cmp_x ) ) / 2 );
115
- }
116
-
117
- }
118
-
119
- // Time to crop the image
120
- $editor->crop( $src_x, $src_y, $src_w, $src_h, $dest_width, $dest_height );
121
-
122
- // Now let's save the image
123
- $saved = $editor->save( $dest_file_name );
124
-
125
- // Get resized image information
126
- $resized_url = str_replace( basename( $url ), basename( $saved['path'] ), $url );
127
- $resized_width = $saved['width'];
128
- $resized_height = $saved['height'];
129
- $resized_type = $saved['mime-type'];
130
-
131
- /**
132
- * Add the resized dimensions to original image metadata
133
- *
134
- * This ensures our resized images are deleted when the original image is deleted from the Media Library
135
- */
136
- $metadata = wp_get_attachment_metadata( $get_attachment[0]->ID );
137
- if ( isset( $metadata['image_meta'] ) ) {
138
- $metadata['image_meta']['resized_images'][] = $resized_width .'x'. $resized_height;
139
- wp_update_attachment_metadata( $get_attachment[0]->ID, $metadata );
140
- }
141
-
142
- // Create the image array
143
- $resized_image = array(
144
- 'url' => $resized_url,
145
- 'width' => $resized_width,
146
- 'height' => $resized_height,
147
- 'type' => $resized_type
148
- );
149
-
150
- }
151
- else {
152
- $resized_image = array(
153
- 'url' => str_replace( basename( $url ), basename( $dest_file_name ), $url ),
154
- 'width' => $dest_width,
155
- 'height' => $dest_height,
156
- 'type' => $ext
157
- );
158
- }
159
-
160
- // And we're done!
161
- return $resized_image;
162
-
163
- }
164
-
165
- /**
166
- * Swaps the image URL with the URL of our resized image, if resizing is enabled.
167
- *
168
- * @param string $image_url The current image URL
169
- * @param object $width The desired image width
170
- * @param object $height The desired image height
171
- * @return object
172
- */
173
- public function resized_image_url( $image_url, $width, $height ) {
174
-
175
- // Resize the image
176
- $resized_image = $this->resize( $image_url, $width, $height, true );
177
-
178
- // Check for errors
179
- if ( ! is_wp_error( $resized_image ) ) {
180
- $image_url = $resized_image['url'];
181
- }
182
-
183
- return $image_url;
184
-
185
- }
186
-
187
- /**
188
- * Deletes any resized images when the original image is deleted from the Wordpress Media Library.
189
- *
190
- * @param int $post_id The attachment ID
191
- * @return void
192
- */
193
- public function delete_resized_attachments( $post_id ) {
194
-
195
- // Get attachment image metadata
196
- $metadata = wp_get_attachment_metadata( $post_id );
197
-
198
- // Bail if we've failed
199
- if ( ! $metadata ) {
200
- return;
201
- }
202
-
203
- // Bail if we don't have the parameters needed to continue
204
- if ( ! isset( $metadata['file'] ) OR ! isset( $metadata['image_meta']['resized_images'] ) ) {
205
- return;
206
- }
207
-
208
- // Establish variables
209
- $pathinfo = pathinfo( $metadata['file'] );
210
- $resized_images = $metadata['image_meta']['resized_images'];
211
-
212
- // Get Wordpress uploads directory
213
- $wp_upload_dir = wp_upload_dir();
214
- $upload_dir = $wp_upload_dir['basedir'];
215
-
216
- // Bail if WordPress uploads directory doesn't exist
217
- if ( ! is_dir( $upload_dir ) ) {
218
- return;
219
- }
220
-
221
- // Delete the resized images
222
- foreach ( $resized_images as $dimensions ) {
223
-
224
- // Get the resized images filename
225
- $file = $upload_dir .'/'. $pathinfo['dirname'] .'/'. $pathinfo['filename'] .'-'. $dimensions .'.'. $pathinfo['extension'];
226
-
227
- // Delete the resized image
228
- @unlink( $file );
229
-
230
- }
231
-
232
- }
233
-
234
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-legacy.php DELETED
@@ -1,704 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Simple helper legacy functions for displaying sliders
12
- *
13
- * @param int $id The legacy slider ID
14
- * @return void
15
- */
16
- if ( ! function_exists( 'easing_slider' ) ) {
17
- function easing_slider() {
18
- echo do_shortcode( "[easingsliderlite]" );
19
- }
20
- }
21
- if ( ! function_exists( 'easingsliderlite' ) ) {
22
- function easingsliderlite() {
23
- echo do_shortcode( "[easingsliderlite]" );
24
- }
25
- }
26
- if ( ! function_exists( 'easingsliderpro' ) ) {
27
- function easingsliderpro( $id ) {
28
- echo do_shortcode( "[easingsliderpro id=\"{$id}\"]" );
29
- }
30
- }
31
- if ( ! function_exists( 'riva_slider_pro' ) ) {
32
- function riva_slider_pro( $id ) {
33
- echo do_shortcode( "[rivasliderpro id=\"{$id}\"]" );
34
- }
35
- }
36
-
37
- /**
38
- * This class ensures a smooth transition from "Lite" or "Pro" to our new unified "Easing Slider" plugin.
39
- *
40
- * Lots of horrible, messy legacy code here that I absolutely hate, but is necessary.
41
- *
42
- * @uses ES_Slider
43
- * @author Matthew Ruddy
44
- */
45
- class ES_Legacy {
46
-
47
- /**
48
- * Gets a Easing Slider "Pro" legacy slider.
49
- *
50
- * @param int $legacy_id The legacy slider ID
51
- * @return ES_Slider|false
52
- */
53
- public function get_pro_slider( $legacy_id ) {
54
-
55
- // Get our "pivot" array option
56
- $pivots = get_option( 'easingslider_pro_slider_pivots' );
57
-
58
- // Bail if we have no pivots
59
- if ( ! $pivots ) {
60
- return false;
61
- }
62
-
63
- // Loop through each pivot and return the match, if we have find one.
64
- foreach ( $pivots as $pivot ) {
65
- if ( $legacy_id == $pivot->legacy_id ) {
66
- return ES_Slider::find( $pivot->id );
67
- }
68
- }
69
-
70
- return false;
71
-
72
- }
73
-
74
- /**
75
- * Creates a Easing Slider "Pro" legacy slider.
76
- *
77
- * @param int $legacy_id The legacy slider ID
78
- * @param string $legacy_title The legacy slider title
79
- * @return ES_Slider
80
- */
81
- public function create_pro_slider( $legacy_id, $legacy_title = null ) {
82
-
83
- // If we don't have a pivot option already, create one. Does nothing otherwise.
84
- add_option( 'easingslider_pro_slider_pivots', array() );
85
-
86
- // Get our "pivot" array option
87
- $pivots = get_option( 'easingslider_pro_slider_pivots' );
88
-
89
- // Create our Easing Slider "Pro" legacy slider
90
- $pro_slider = ES_Slider::create();
91
- $pro_slider->post_title = easingslider_validate_data( $legacy_title );
92
- $pro_slider->save();
93
-
94
- // Populate the pivot
95
- $pivot = (object) array( 'legacy_id' => (int) $legacy_id, 'id' => (int) $pro_slider->ID );
96
-
97
- // Save to our pivots
98
- update_option( 'easingslider_pro_slider_pivots', array_merge( $pivots, array( $pivot ) ) );
99
-
100
- return $pro_slider;
101
-
102
- }
103
-
104
- /**
105
- * Deletes the Easing Slider "Pro" related options when the slider itself is deleted.
106
- *
107
- * @param int $id The slider ID
108
- * @return void
109
- */
110
- public function delete_pro_slider( $id ) {
111
-
112
- // Get the "pivot" array option
113
- $pivots = get_option( 'easingslider_pro_slider_pivots' );
114
-
115
- // Bail if we have no pivots
116
- if ( ! $pivots ) {
117
- return;
118
- }
119
-
120
- // Loop through and find a matching pivot
121
- foreach ( $pivots as $key => $pivot ) {
122
- if ( $id == $pivot->id ) {
123
- unset( $pivots[ $key ] );
124
-
125
- update_option( 'easingslider_pro_slider_pivots', $pivots );
126
- }
127
- }
128
-
129
- // If pivots are empty, delete the option altogether.
130
- if ( count( $pivots ) == 0 ) {
131
- delete_option( 'easingslider_pro_slider_pivots' );
132
- }
133
-
134
- }
135
-
136
- /**
137
- * Renders our Easing Slider "Pro" shortcode
138
- *
139
- * @param int $legacy_id The legacy slider ID
140
- * @return string
141
- */
142
- public function render_pro_slider( $legacy_id ) {
143
-
144
- // Get our "Pro" slider
145
- $pro_slider = $this->get_pro_slider( $legacy_id );
146
-
147
- // Bail if we don't have a slider
148
- if ( ! $pro_slider ) {
149
- return;
150
- }
151
-
152
- return $pro_slider->render();
153
-
154
- }
155
-
156
- /**
157
- * Handle the functionality for our Easing Slider "Pro" shortcode
158
- *
159
- * @param array $atts The shortcode attributes
160
- * @return string
161
- */
162
- public function do_pro_shortcode( $atts ) {
163
-
164
- // Extract shortcode attributes
165
- extract(
166
- shortcode_atts(
167
- array( 'id' => false ),
168
- $atts
169
- )
170
- );
171
-
172
- // Display error message if no ID has been entered
173
- if ( ! $id ) {
174
- return __( 'Looks like you\'ve forgotten to add a slideshow ID to this shortcode. Oh dear!', 'easingslider' );
175
- }
176
-
177
- return $this->render_pro_slider( $id );
178
-
179
- }
180
-
181
- /**
182
- * Upgrades the plugin from Easing Slider "Pro" v1.0 and onwards (was known as Riva Slider "Pro" at this time).
183
- *
184
- * @return void
185
- */
186
- public function pro_upgrade_from_100() {
187
-
188
- global $wpdb;
189
-
190
- // Bail if this has already been carried out
191
- if ( get_option( 'easingslider_upgraded_from_pro' ) ) {
192
- return;
193
- }
194
-
195
- // Bail if we don't have a version, telling us that the plugin wasn't installed and there is nothing to update.
196
- if ( ! get_option( 'riva_slider_pro_version' ) ) {
197
- return;
198
- }
199
-
200
- // Get the legacy sliders
201
- $legacy_sliders = get_option( 'riva_slider_pro_slideshows' );
202
-
203
- // Add the sliders, if we have any.
204
- if ( $legacy_sliders ) {
205
- foreach ( $legacy_sliders as $legacy_slider ) {
206
-
207
- // Create the Easing Slider "Pro" slider
208
- $slider = $this->create_pro_slider( $legacy_slider['id'], $legacy_slider['name'] );
209
-
210
- // Transfer the data
211
- $slider->general->randomize = ( ! empty( $legacy_slider['random_order'] ) ) ? true : false;
212
- $slider->dimensions->width = easingslider_validate_data( $legacy_slider['width'] );
213
- $slider->dimensions->height = easingslider_validate_data( $legacy_slider['height'] );
214
- $slider->transitions->duration = easingslider_validate_data( $legacy_slider['trans_time'] );
215
- $slider->navigation->arrows = ( $legacy_slider['direction_nav'] == 'enable' ) ? true : false;
216
- $slider->navigation->arrows_hover = easingslider_validate_data( $legacy_slider['direction_nav_hover'] );
217
- $slider->navigation->arrows_position = easingslider_validate_data( $legacy_slider['direction_nav_position'] );
218
- $slider->navigation->pagination = ( $legacy_slider['control_nav'] == 'enable' ) ? true : false;
219
- $slider->navigation->pagination_location = easingslider_validate_data( str_replace( '_', '-', $old_slideshow['control_nav_pos'] ) );
220
-
221
- // Add the slides
222
- foreach ( $legacy_slider['images'] as $key => $legacy_slide ) {
223
-
224
- // Query the guid
225
- $attachment_query = $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE guid='%s'", $legacy_slide['image-url'] );
226
-
227
- // Attempt to get the attachment of this image
228
- $attachment_id = $wpdb->get_var( $attachment_query );
229
-
230
- // Populate the slide
231
- $slide = (object) array(
232
- 'id' => easingslider_validate_data( ( $key + 1 ) ),
233
- 'attachment_id' => easingslider_validate_data( $attachment_id ),
234
- 'type' => 'image',
235
- 'alt' => easingslider_validate_data( $legacy_slide['image-alt'] ),
236
- 'aspectRatio' => null,
237
- 'link' => 'custom',
238
- 'linkUrl' => ( 'webpage' == $legacy_slide['image-link'] ) ? $legacy_slide['webpage-url'] : $legacy_slide['video-url'],
239
- 'linkTargetBlank' => false,
240
- 'title' => easingslider_validate_data( $legacy_slide['image-title'] )
241
- );
242
-
243
- // Add an image URL if we aren't using an attachment
244
- if ( ! $attachment_id ) {
245
- $slide->url = easingslider_validate_data( $legacy_slide['image-url'] );
246
- }
247
-
248
- // Validate & add the slide
249
- $slider->slides[] = easingslider_validate_data( $slide );
250
-
251
- }
252
-
253
- // Save the slider
254
- $slider->save();
255
-
256
- }
257
- }
258
-
259
- // Flag that this update has been done
260
- update_option( 'easingslider_upgraded_from_pro', true );
261
-
262
- }
263
-
264
- /**
265
- * Upgrades the plugin from Easing Slider "Pro" v2.0 and onwards.
266
- *
267
- * @return void
268
- */
269
- public function pro_upgrade_from_200() {
270
-
271
- global $wpdb;
272
-
273
- // Bail if this has already been carried out
274
- if ( get_option( 'easingslider_upgraded_from_pro' ) ) {
275
- return;
276
- }
277
-
278
- // Bail if we don't have a version, telling us that the plugin wasn't installed and there is nothing to update.
279
- if ( ! get_option( 'easingsliderpro_version' ) ) {
280
- return;
281
- }
282
-
283
- // Get the legacy sliders
284
- $legacy_sliders = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}easingsliderpro" );
285
-
286
- // Add the sliders, if we have any.
287
- if ( $legacy_sliders ) {
288
- foreach ( $legacy_sliders as $legacy_slider ) {
289
-
290
- // Create the Easing Slider "Pro" slider
291
- $slider = $this->create_pro_slider( $legacy_slider->id, $legacy_slider->name );
292
-
293
- // Decode the legacy slider's json
294
- $legacy_slider->general = json_decode( $legacy_slider->general );
295
- $legacy_slider->dimensions = json_decode( $legacy_slider->dimensions );
296
- $legacy_slider->transitions = json_decode( $legacy_slider->transitions );
297
- $legacy_slider->navigation = json_decode( $legacy_slider->navigation );
298
- $legacy_slider->playback = json_decode( $legacy_slider->playback );
299
- $legacy_slider->slides = json_decode( $legacy_slider->slides );
300
-
301
- // Transfer the data
302
- $slider->general->randomize = easingslider_validate_data( $legacy_slider->general->randomize );
303
- $slider->dimensions->width = easingslider_validate_data( $legacy_slider->dimensions->width );
304
- $slider->dimensions->height = easingslider_validate_data( $legacy_slider->dimensions->height );
305
- $slider->dimensions->responsive = easingslider_validate_data( $legacy_slider->dimensions->responsive );
306
- $slider->transitions->effect = easingslider_validate_data( $legacy_slider->transitions->effect );
307
- $slider->transitions->duration = easingslider_validate_data( $legacy_slider->transitions->duration );
308
- $slider->navigation->arrows = easingslider_validate_data( $legacy_slider->navigation->arrows );
309
- $slider->navigation->arrows_hover = easingslider_validate_data( $legacy_slider->navigation->arrows_hover );
310
- $slider->navigation->arrows_position = easingslider_validate_data( $legacy_slider->navigation->arrows_position );
311
- $slider->navigation->pagination = easingslider_validate_data( $legacy_slider->navigation->pagination );
312
- $slider->navigation->pagination_hover = easingslider_validate_data( $legacy_slider->navigation->pagination_hover );
313
- $slider->navigation->pagination_position = easingslider_validate_data( $legacy_slider->navigation->pagination_position );
314
- $slider->navigation->pagination_location = easingslider_validate_data( $legacy_slider->navigation->pagination_location );
315
- $slider->playback->enabled = easingslider_validate_data( $legacy_slider->playback->enabled );
316
- $slider->playback->pause = easingslider_validate_data( $legacy_slider->playback->pause );
317
-
318
- // Add the slides
319
- foreach ( $legacy_slider->slides as $legacy_slide ) {
320
-
321
- // Query the guid
322
- $attachment_query = $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE guid='%s'", $legacy_slide->url );
323
-
324
- // Attempt to get the attachment of this image
325
- $attachment_id = $wpdb->get_var( $attachment_query );
326
-
327
- // Populate the slide
328
- $slide = (object) array(
329
- 'id' => easingslider_validate_data( $legacy_slide->id ),
330
- 'attachment_id' => easingslider_validate_data( $attachment_id ),
331
- 'type' => 'image',
332
- 'alt' => easingslider_validate_data( $legacy_slide->alt ),
333
- 'aspectRatio' => null,
334
- 'link' => ( $legacy_slide->link ) ? 'custom' : 'none',
335
- 'linkUrl' => easingslider_validate_data( $legacy_slide->link ),
336
- 'linkTargetBlank' => ( '_blank' == $legacy_slide->linkTarget ) ? '_blank': false,
337
- 'title' => easingslider_validate_data( $legacy_slide->title )
338
- );
339
-
340
- // Add an image URL if we aren't using an attachment
341
- if ( ! $attachment_id ) {
342
- $slide->url = easingslider_validate_data( $legacy_slide->url );
343
- }
344
-
345
- // Validate & add the slide
346
- $slider->slides[] = easingslider_validate_data( $slide );
347
-
348
- }
349
-
350
- // Save the slider
351
- $slider->save();
352
-
353
- }
354
- }
355
-
356
- // Get the settings
357
- $settings = get_option( 'easingslider_settings' );
358
-
359
- // Get the legacy settings
360
- $legacy_settings = get_option( "easingsliderpro_settings" );
361
-
362
- // Transfer the settings
363
- $settings->load_assets = $legacy_settings['load_scripts'];
364
- $settings->image_resizing = $legacy_settings['resizing'];
365
-
366
- // Save the settings
367
- update_option( 'easingslider_settings', $settings );
368
-
369
- // Flag that this update has been done
370
- update_option( 'easingslider_upgraded_from_pro', true );
371
-
372
- }
373
-
374
- /**
375
- * Gets the Easing Slider "Lite" legacy slider.
376
- *
377
- * @return ES_Slider|false
378
- */
379
- public function get_lite_slider() {
380
-
381
- // Get the ID of our "Lite" slider
382
- $lite_id = get_option( 'easingslider_lite_slider_id' );
383
-
384
- // Get the Easing Slider "Lite" slider
385
- $lite_slider = ES_Slider::find( $lite_id );
386
-
387
- return $lite_slider;
388
-
389
- }
390
-
391
- /**
392
- * Creates the Easing Slider "Lite" legacy slider.
393
- *
394
- * @return ES_Slider
395
- */
396
- public function create_lite_slider() {
397
-
398
- // Create the slider
399
- $lite_slider = ES_Slider::create();
400
- $lite_slider->post_title = 'Easing Slider "Lite"';
401
- $lite_slider->save();
402
-
403
- // Save the Easing Slider "Lite" slider ID
404
- update_option( 'easingslider_lite_slider_id', $lite_slider->ID );
405
-
406
- return $lite_slider;
407
-
408
- }
409
-
410
- /**
411
- * Deletes the Easing Slider "Lite" related options when the slider itself is deleted.
412
- *
413
- * @param int $id The slider ID
414
- * @return void
415
- */
416
- public function delete_lite_slider( $id ) {
417
-
418
- // If we've deleted the Easing Slider "Lite" slider, delete its options.
419
- if ( $id == get_option( 'easingslider_lite_slider_id' ) ) {
420
- delete_option( 'easingslider_lite_slider_id' );
421
- }
422
-
423
- }
424
-
425
- /**
426
- * Renders our Easing Slider "Lite" shortcode
427
- *
428
- * @return string
429
- */
430
- public function render_lite_slider() {
431
-
432
- // Get our "Lite" slider
433
- $lite_slider = $this->get_lite_slider();
434
-
435
- // Bail if we don't have a slider
436
- if ( ! $lite_slider ) {
437
- return;
438
- }
439
-
440
- return $lite_slider->render();
441
-
442
- }
443
-
444
- /**
445
- * Handle the functionality for our Easing Slider "Lite" shortcode
446
- *
447
- * @return string
448
- */
449
- public function do_lite_shortcode() {
450
-
451
- return $this->render_lite_slider();
452
-
453
- }
454
-
455
- /**
456
- * This method handles shortcodes from v1 of Easing Slider, which used the same shortcode as we do now.
457
- *
458
- * To work around it, this method will check for no attributes on the shortcode, as we previously didn't support them.
459
- * If this is true, it will search for an Easing Slider "Lite" slider and display it if found.
460
- *
461
- * Quite messy, but that version of the plugin was some of my first ever PHP, so bare with me :)
462
- *
463
- * @param array $atts The shortcode attributes
464
- * @return void
465
- */
466
- public function handle_lite_shortcode( $atts ) {
467
-
468
- // Bail if attributes aren't empty
469
- if ( ! empty( $atts['id'] ) ) {
470
- return;
471
- }
472
-
473
- // Get our "Lite" slider
474
- $lite_slider = $this->get_lite_slider();
475
-
476
- // Bail if we don't have one
477
- if ( ! $lite_slider ) {
478
- return;
479
- }
480
-
481
- // Render our "Lite" slider
482
- echo $lite_slider->render();
483
-
484
- }
485
-
486
- /**
487
- * Upgrades the plugin from Easing Slider "Lite" v1.0 and onwards.
488
- *
489
- * @return void
490
- */
491
- public function lite_upgrade_from_100() {
492
-
493
- // Bail if this has already been carried out
494
- if ( get_option( 'easingslider_upgraded_from_lite' ) ) {
495
- return;
496
- }
497
-
498
- /**
499
- * This version of the plugin had no "version" option, so we have to improvise.
500
- *
501
- * To do this, we will cycle through the options used to store the images from #1 to #10.
502
- * If we find an image, we will assume the plugin settings exist and will continue with the update.
503
- */
504
- $legacy_images = array( 'sImg1', 'sImg2', 'sImg3', 'sImg4', 'sImg5', 'sImg6', 'sImg7', 'sImg8', 'sImg9', 'sImg10' );
505
-
506
- // Loop through each image option, and continue if we find a match.
507
- foreach ( $legacy_images as $legacy_image ) {
508
-
509
- // Continue if we find an image, telling us that the plugin was being used
510
- if ( get_option( $legacy_image ) ) {
511
-
512
- // Create the Easing Slider "Lite" slider
513
- $slider = $this->create_lite_slider();
514
-
515
- // Transfer the data
516
- $slider->dimensions->width = easingslider_validate_data( get_option( 'width' ) );
517
- $slider->dimensions->height = easingslider_validate_data( get_option( 'height' ) );
518
- $slider->dimensions->responsive = false;
519
- $slider->transitions->effect = ( get_option( 'transition' ) == 'fade' ) ? 'fade' : 'slide';
520
- $slider->transitions->duration = easingslider_validate_data( get_option( 'transpeed' ) );
521
- $slider->navigation->arrows = ( get_option( 'buttons' ) == '' ) ? false : true;
522
- $slider->navigation->pagination = ( get_option( 'sPagination' ) == '' ) ? false : true;
523
- $slider->playback->pause = easingslider_validate_data( get_option( 'interval' ) );
524
-
525
- // Add the slides. We used to have a maximum of ten, hence the "for" loop.
526
- for ( $i = 1; $i <= 10; $i++ ) {
527
-
528
- // Get the image
529
- $image = get_option( "sImg{$i}" );
530
-
531
- // Bail if the image doesn't exist
532
- if ( empty( $image ) ) {
533
- continue;
534
- }
535
-
536
- // Push the slide data
537
- $slider->slides[] = (object) array(
538
- 'id' => $i,
539
- 'attachment_id' => null,
540
- 'type' => 'image',
541
- 'alt' => '',
542
- 'aspectRatio' => null,
543
- 'link' => ( get_option( "sImgLink{$i}" ) == '' ) ? 'none' : 'custom',
544
- 'linkUrl' => easingslider_validate_data( get_option( "sImgLink{$i}" ) ),
545
- 'linkTargetBlank' => false,
546
- 'title' => '',
547
- 'url' => easingslider_validate_data( $image )
548
- );
549
-
550
- }
551
-
552
- // Save the slider
553
- $slider->save();
554
-
555
- // Flag that this update has been done
556
- update_option( 'easingslider_upgraded_from_lite', true );
557
-
558
- // We've done our update. Time to bail!
559
- return;
560
-
561
- }
562
-
563
- }
564
-
565
- }
566
-
567
- /**
568
- * Upgrades the plugin from Easing Slider "Lite" v2.0 and onwards.
569
- *
570
- * @return void
571
- */
572
- public function lite_upgrade_from_200() {
573
-
574
- global $wpdb;
575
-
576
- // Bail if this has already been carried out
577
- if ( get_option( 'easingslider_upgraded_from_lite' ) ) {
578
- return;
579
- }
580
-
581
- /**
582
- * In my previous attempts to change the plugin name from "Easing Slider" to "Riva Slider",
583
- * I made the catastrophic mistake of changing the plugin directory name and options, etc, which
584
- * created dozens of issues and prompted the name change reversal.
585
- *
586
- * As a result, it's possible options may exist under the prefix "rivaslider" or "easingslider".
587
- * Let's accommodate for both.
588
- */
589
- $plugin_slug = ( get_option( 'easingsliderlite_version' ) ) ? 'easingsliderlite' : 'rivasliderlite';
590
-
591
- // Bail if we don't have a version, telling us that the plugin wasn't installed and there is nothing to update.
592
- if ( ! get_option( "{$plugin_slug}_version" ) ) {
593
- return;
594
- }
595
-
596
- // Create the Easing Slider "Lite" slider
597
- $slider = $this->create_lite_slider();
598
-
599
- // Get the legacy slider
600
- $legacy_slider = get_option( "{$plugin_slug}_slideshow" );
601
-
602
- // Transfer the data
603
- $slider->general->randomize = easingslider_validate_data( $legacy_slider->general->randomize );
604
- $slider->dimensions->width = easingslider_validate_data( $legacy_slider->dimensions->width );
605
- $slider->dimensions->height = easingslider_validate_data( $legacy_slider->dimensions->height );
606
- $slider->dimensions->responsive = easingslider_validate_data( $legacy_slider->dimensions->responsive );
607
- $slider->transitions->effect = easingslider_validate_data( $legacy_slider->transitions->effect );
608
- $slider->transitions->duration = easingslider_validate_data( $legacy_slider->transitions->duration );
609
- $slider->navigation->arrows = easingslider_validate_data( $legacy_slider->navigation->arrows );
610
- $slider->navigation->arrows_hover = easingslider_validate_data( $legacy_slider->navigation->arrows_hover );
611
- $slider->navigation->arrows_position = easingslider_validate_data( $legacy_slider->navigation->arrows_position );
612
- $slider->navigation->pagination = easingslider_validate_data( $legacy_slider->navigation->pagination );
613
- $slider->navigation->pagination_hover = easingslider_validate_data( $legacy_slider->navigation->pagination_hover );
614
- $slider->navigation->pagination_position = easingslider_validate_data( $legacy_slider->navigation->pagination_position );
615
- $slider->navigation->pagination_location = easingslider_validate_data( $legacy_slider->navigation->pagination_location );
616
- $slider->playback->enabled = easingslider_validate_data( $legacy_slider->playback->enabled );
617
- $slider->playback->pause = easingslider_validate_data( $legacy_slider->playback->pause );
618
-
619
- // Add the slides
620
- foreach ( $legacy_slider->slides as $legacy_slide ) {
621
-
622
- // Query the guid
623
- $attachment_query = $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE guid='%s'", $legacy_slide->url );
624
-
625
- // Attempt to get the attachment of this image
626
- $attachment_id = $wpdb->get_var( $attachment_query );
627
-
628
- // Populate the slide
629
- $slide = (object) array(
630
- 'id' => easingslider_validate_data( $legacy_slide->id ),
631
- 'attachment_id' => easingslider_validate_data( $attachment_id ),
632
- 'type' => 'image',
633
- 'alt' => easingslider_validate_data( $legacy_slide->alt ),
634
- 'aspectRatio' => null,
635
- 'link' => ( $legacy_slide->link ) ? 'custom' : 'none',
636
- 'linkUrl' => easingslider_validate_data( $legacy_slide->link ),
637
- 'linkTargetBlank' => ( '_blank' == $legacy_slide->linkTarget ) ? '_blank': false,
638
- 'title' => easingslider_validate_data( $legacy_slide->title )
639
- );
640
-
641
- // Add an image URL if we aren't using an attachment
642
- if ( ! $attachment_id ) {
643
- $slide->url = easingslider_validate_data( $legacy_slide->url );
644
- }
645
-
646
- // Validate & add the slide
647
- $slider->slides[] = easingslider_validate_data( $slide );
648
-
649
- }
650
-
651
- // Save the slider
652
- $slider->save();
653
-
654
- // Get the settings
655
- $settings = get_option( 'easingslider_settings' );
656
-
657
- // Get the legacy settings
658
- $legacy_settings = get_option( "{$plugin_slug}_settings" );
659
-
660
- // Transfer the settings
661
- $settings->load_assets = $legacy_settings['load_scripts'];
662
- $settings->image_resizing = $legacy_settings['resizing'];
663
-
664
- // Save the settings
665
- update_option( 'easingslider_settings', $settings );
666
-
667
- // Flag that this update has been done
668
- update_option( 'easingslider_upgraded_from_lite', true );
669
-
670
- }
671
-
672
- /**
673
- * Redirects all users upgrading from legacy versions to the "What's New" page after activation
674
- *
675
- * @return void
676
- */
677
- public function redirect_to_whats_new() {
678
-
679
- // Check for previous versions
680
- if ( get_option( 'riva_slider_pro_version' ) OR get_option( 'easingsliderpro_version' ) OR get_option( 'rivasliderlite_version' ) OR get_option( 'easingsliderlite_version' ) ) {
681
-
682
- // Redirect to "What's New"
683
- wp_safe_redirect( admin_url( 'index.php?page=easingslider-about' ) );
684
- exit;
685
-
686
- }
687
-
688
- }
689
-
690
- /**
691
- * Deletes all the legacy related options.
692
- *
693
- * @return void
694
- */
695
- public function remove_options() {
696
-
697
- delete_option( 'easingslider_lite_slider_id' );
698
- delete_option( 'easingslider_pro_slider_pivots' );
699
- delete_option( 'easingslider_upgraded_from_lite' );
700
- delete_option( 'easingslider_upgraded_from_pro' );
701
-
702
- }
703
-
704
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-menu.php DELETED
@@ -1,109 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Class for creating our toplevel admin menu.
12
- *
13
- * @author Matthew Ruddy
14
- */
15
- class ES_Menu {
16
-
17
- /**
18
- * Adds the plugin toplevel menu
19
- *
20
- * @return void
21
- */
22
- public function add_toplevel_menu() {
23
-
24
- global $menu;
25
-
26
- // Default menu positioning
27
- $position = '100.1';
28
-
29
- // If enabled, relocate the plugin menus higher
30
- if ( apply_filters( 'easingslider_relocate_menus', __return_true() ) ) {
31
-
32
- for ( $position = '40.1'; $position <= '100.1'; $position += '0.1' ) {
33
-
34
- // Ensure there is a space before and after each position we are checking, leaving room for our separators.
35
- $before = $position - '0.1';
36
- $after = $position + '0.1';
37
-
38
- // Do the checks for each position. These need to be strings, hence the quotation marks.
39
- if ( isset( $menu[ "$position" ] ) ) {
40
- continue;
41
- }
42
- if ( isset( $menu[ "$before" ] ) ) {
43
- continue;
44
- }
45
- if ( isset( $menu[ "$after" ] ) ) {
46
- continue;
47
- }
48
-
49
- // If we've successfully gotten this far, break the loop. We've found the position we need.
50
- break;
51
-
52
- }
53
-
54
- }
55
-
56
- // Add toplevel menu
57
- add_menu_page(
58
- __( 'Sliders', 'easingslider' ),
59
- __( 'Sliders', 'easingslider' ),
60
- 'easingslider_edit_sliders',
61
- 'easingslider_edit_sliders',
62
- null,
63
- 'dashicons-images-alt',
64
- "$position"
65
- );
66
-
67
- // Do action allowing extension to add their own toplevel menus
68
- do_action( 'easingslider_add_toplevel_menu', $position );
69
-
70
- // Add the menu separators if menus have been relocated (they are by default). Quotations marks ensure these are strings.
71
- if ( apply_filters( 'easingslider_relocate_menus', __return_true() ) ) {
72
- $this->add_menu_separator( "$before" );
73
- $this->add_menu_separator( "$after" );
74
- }
75
-
76
- }
77
-
78
- /**
79
- * Create a separator in the admin menus, above and below our plugin menus
80
- *
81
- * @param string $position The menu position to insert the separator
82
- * @return void
83
- */
84
- protected function add_menu_separator( $position = '40.1' ) {
85
-
86
-
87
- global $menu;
88
-
89
- $index = 0;
90
- foreach ( $menu as $offset => $section ) {
91
-
92
- if ( 'separator' == substr( $section[2], 0, 9 ) ) {
93
- $index++;
94
- }
95
-
96
- if ( $offset >= $position ) {
97
-
98
- // Quotation marks ensures the position is a string. Integers won't work if we are using decimal values.
99
- $menu[ "$position" ] = array( '', 'read', "separator{$index}", '', 'wp-menu-separator' );
100
- break;
101
-
102
- }
103
-
104
- }
105
- ksort( $menu );
106
-
107
- }
108
-
109
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-migrations.php DELETED
@@ -1,105 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Defines the version migrations.
12
- *
13
- * All of our update procedures can be found here.
14
- *
15
- * @uses Easing_Slider
16
- * @author Matthew Ruddy
17
- */
18
- class ES_Migrations {
19
-
20
- /**
21
- * Do migrations
22
- *
23
- * @return void
24
- */
25
- public function do_migrations() {
26
-
27
- // Get the plugin version
28
- $version = get_option( 'easingslider_version' );
29
-
30
- // Hook additional functionality
31
- do_action( 'easingslider_update_plugin', $version );
32
-
33
- }
34
-
35
- /**
36
- * Updates the plugin to v2.2.
37
- *
38
- * @param int $version The current plugin version
39
- * @return void
40
- */
41
- public function migrate_to_22( $version ) {
42
-
43
- /**
44
- * Do the update if we have no version (just upgraded from Easing Slider "Lite" or "Pro"), or if we have a version number
45
- * below v2.2 (possible from very early versions of the plugin).
46
- */
47
- if ( ! $version OR version_compare( $version, '2.2', '<' ) ) {
48
-
49
- // Trigger activation
50
- Easing_Slider::do_activation();
51
-
52
- }
53
-
54
- }
55
-
56
- /**
57
- * Updates the plugin to v2.2.1.
58
- *
59
- * @param int $version The current plugin version
60
- * @return void
61
- */
62
- public function migrate_to_221( $version ) {
63
-
64
- // Continue if upgrading from a lower version
65
- if ( version_compare( $version, '2.2.1', '<' ) ) {
66
-
67
- // Get the settings
68
- $settings = get_option( 'easingslider_settings' );
69
-
70
- // Bail if we have no settings or the setting we need
71
- if ( ! $settings OR ! isset( $settings->image_resizing ) ) {
72
- return;
73
- }
74
-
75
- // Get all sliders
76
- $sliders = ES_Slider::all();
77
-
78
- // Migrate the "Image Resizing" option
79
- foreach ( $sliders as $slider ) {
80
- $slider->dimensions->image_resizing = $settings->image_resizing;
81
- $slider->save();
82
- }
83
-
84
- // Unset the settings option
85
- unset( $settings->image_resizing );
86
-
87
- // Update the settings
88
- update_option( 'easingslider_settings', $settings );
89
-
90
- }
91
-
92
- }
93
-
94
- /**
95
- * Updates the plugin version
96
- *
97
- * @return void
98
- */
99
- public function update_version() {
100
-
101
- update_option( 'easingslider_version', Easing_Slider::$version );
102
-
103
- }
104
-
105
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-settings-page.php DELETED
@@ -1,205 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Defines our admin settings.
12
- *
13
- * @uses Easing_Slider
14
- * @author Matthew Ruddy
15
- */
16
- class ES_Settings_Page {
17
-
18
- /**
19
- * Adds our settings user capabilities
20
- *
21
- * @return void
22
- */
23
- public function add_capabilities() {
24
-
25
- // Get user role
26
- $role = get_role( 'administrator' );
27
-
28
- // Add the capability
29
- $role->add_cap( 'easingslider_manage_settings' );
30
-
31
- }
32
-
33
- /**
34
- * Removes our settings user capabilities
35
- *
36
- * @return void
37
- */
38
- public function remove_capabilities() {
39
-
40
- // Get user role
41
- $role = get_role( 'administrator' );
42
-
43
- // Remove the capability
44
- $role->remove_cap( 'easingslider_manage_settings' );
45
-
46
- }
47
-
48
- /**
49
- * Adds our "Settings" page to the plugin admin menu
50
- *
51
- * @return void
52
- */
53
- public function add_submenu_page() {
54
-
55
- // "Settings" page
56
- $hook = add_submenu_page(
57
- 'easingslider_edit_sliders',
58
- __( 'Edit Settings', 'easingslider' ),
59
- __( 'Settings', 'easingslider' ),
60
- 'easingslider_manage_settings',
61
- 'easingslider_manage_settings',
62
- array( $this, 'display_view' )
63
- );
64
-
65
- // Page-specific hooks
66
- add_action( "load-{$hook}", array( $this, 'do_actions' ) );
67
- add_action( "admin_print_styles-{$hook}", array( $this, 'enqueue_styles' ) );
68
-
69
- }
70
-
71
- /**
72
- * Registers all of our settings assets
73
- *
74
- * @return void
75
- */
76
- public function register_assets() {
77
-
78
- // Get our directory
79
- $css_dir = plugin_dir_url( Easing_Slider::$file ) . 'css';
80
-
81
- // Get file suffix
82
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
83
-
84
- // Register our stylesheet
85
- wp_register_style( 'easingslider-settings-page', "{$css_dir}/settings-page{$suffix}.css", false, Easing_Slider::$version );
86
-
87
- }
88
-
89
- /**
90
- * Enqueues all of our settings styles
91
- *
92
- * @return void
93
- */
94
- public function enqueue_styles() {
95
-
96
- // Enqueue our stylesheet
97
- wp_enqueue_style( 'easingslider-settings-page' );
98
-
99
- }
100
-
101
- /**
102
- * Gets the tabs for our "Settings" page
103
- *
104
- * @return array
105
- */
106
- public function get_tabs() {
107
-
108
- return apply_filters( 'easingslider_settings_tabs', array(
109
- 'general' => __( 'General', 'easingslider' ),
110
- 'licenses' => __( 'Licenses', 'easingslider' )
111
- ) );
112
-
113
- }
114
-
115
- /**
116
- * Gets the current "Settings" tab
117
- *
118
- * @return string
119
- */
120
- public function current_tab() {
121
-
122
- return ( isset( $_GET['tab'] ) ) ? sanitize_key( $_GET['tab'] ) : 'general';
123
-
124
- }
125
-
126
- /**
127
- * Gets our form fields
128
- *
129
- * @return array
130
- */
131
- public function get_form_fields() {
132
-
133
- $data = apply_filters( 'easingslider_pre_get_settings_form_fields', array() );
134
-
135
- // Set the form fields
136
- if ( isset( $_POST['settings'] ) && is_array( $_POST['settings'] ) ) {
137
- $data = easingslider_validate_data( array_merge( $data, $_POST['settings'] ) );
138
- }
139
-
140
- return $data;
141
-
142
- }
143
-
144
- /**
145
- * Does our actions
146
- *
147
- * @return void
148
- */
149
- public function do_actions() {
150
-
151
- // Continue if the save button has been pressed
152
- if ( isset( $_POST['save'] ) ) {
153
-
154
- // Bail if nonce is invalid
155
- if ( ! check_admin_referer( 'save' ) ) {
156
- return;
157
- }
158
-
159
- // Get the current settings
160
- $settings = get_option( 'easingslider_settings' );
161
-
162
- // Merge the updated settings
163
- $settings = (object) array_merge( (array) $settings, $this->get_form_fields() );
164
-
165
- // Update the settings
166
- update_option( 'easingslider_settings', $settings );
167
-
168
- // Trigger actions
169
- do_action( 'easingslider_save_settings_actions' );
170
-
171
- // Tell the user
172
- easingslider_show_notice( __( 'Settings have been saved successfully.', 'easingslider' ), 'updated' );
173
-
174
- }
175
-
176
- // Trigger actions
177
- do_action( 'easingslider_do_settings_actions' );
178
-
179
- }
180
-
181
- /**
182
- * Displays the view
183
- *
184
- * @return void
185
- */
186
- public function display_view() {
187
-
188
- // Get the current page
189
- $page = sanitize_key( $_GET['page'] );
190
-
191
- // Get the settings
192
- $settings = get_option( 'easingslider_settings' );
193
-
194
- // Get the tabs
195
- $tabs = $this->get_tabs();
196
-
197
- // Get the current tab
198
- $current_tab = $this->current_tab();
199
-
200
- // Display the view
201
- require plugin_dir_path( dirname( __FILE__ ) ) . 'partials/edit-settings.php';
202
-
203
- }
204
-
205
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-shortcode.php DELETED
@@ -1,170 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Defines our shortcode functionality
12
- *
13
- * @uses ES_Slider
14
- * @author Matthew Ruddy
15
- */
16
- class ES_Shortcode {
17
-
18
- /**
19
- * Prints the "Add Slider" media thickbox
20
- *
21
- * @return void
22
- */
23
- public function print_media_thickbox() {
24
-
25
- global $pagenow;
26
-
27
- // Bail if not in the post/page editor
28
- if ( ( 'post.php' OR 'post-new.php' ) != $pagenow ) {
29
- return;
30
- }
31
-
32
- // Get all sliders
33
- $sliders = ES_Slider::all();
34
-
35
- // Display the thickbox
36
- ?>
37
- <style type="text/css">
38
- .section {
39
- padding: 15px 15px 0 15px;
40
- }
41
- </style>
42
-
43
- <script type="text/javascript">
44
- /**
45
- * Sends a shortcode to the post/page editor
46
- */
47
- function insertSlider() {
48
-
49
- // Get the slider ID
50
- var id = jQuery('#slider').val();
51
-
52
- // Display alert and bail if no slideshow was selected
53
- if ( '-1' === id ) {
54
- return alert("<?php _e( 'Please select a slider', 'easingslider' ); ?>");
55
- }
56
-
57
- // Send shortcode to editor
58
- send_to_editor('[easingslider id="'+ id +'"]');
59
-
60
- // Close thickbox
61
- tb_remove();
62
-
63
- }
64
- </script>
65
-
66
- <div id="select-slider" style="display: none;">
67
- <div class="section">
68
- <h2><?php _e( 'Add a slider', 'easingslider' ); ?></h2>
69
- <span><?php _e( 'Select a slider to insert from the box below.', 'easingslider' ); ?></span>
70
- </div>
71
-
72
- <div class="section">
73
- <select name="slider" id="slider">
74
- <option value="-1"><?php _e( 'Select a slider', 'easingslider' ); ?></option>
75
- <?php
76
- foreach ( $sliders as $slider ) {
77
- echo "<option value=\"{$slider->ID}\">{$slider->post_title} (ID #{$slider->ID})</option>";
78
- }
79
- ?>
80
- </select>
81
- </div>
82
-
83
- <div class="section">
84
- <button id="insert-slider" class="button-primary" onClick="insertSlider();"><?php _e( 'Insert Slider', 'easingslider' ); ?></button>
85
- <button id="close-slider-thickbox" class="button-secondary" style="margin-left: 5px;" onClick="tb_remove();"><?php _e( 'Close', 'easingslider' ); ?></a>
86
- </div>
87
- </div>
88
- <?php
89
-
90
- }
91
-
92
- /**
93
- * Prints the "Add Slider" media button
94
- *
95
- * @param int $editor_id The editor ID
96
- * @return void
97
- */
98
- public function print_media_button( $editor_id ) {
99
-
100
- // Print the button's HTML and CSS
101
- ?>
102
- <style type="text/css">
103
- .wp-media-buttons .insert-slider span.wp-media-buttons-icon {
104
- margin-top: -2px;
105
- }
106
- .wp-media-buttons .insert-slider span.wp-media-buttons-icon:before {
107
- content: "\f232";
108
- font: 400 18px/1 dashicons;
109
- speak: none;
110
- -webkit-font-smoothing: antialiased;
111
- -moz-osx-font-smoothing: grayscale;
112
- }
113
- </style>
114
-
115
- <a href="#TB_inline?width=480&amp;inlineId=select-slider" class="button thickbox insert-slider" data-editor="<?php echo esc_attr( $editor_id ); ?>" title="<?php _e( 'Add a Slider', 'easingslider' ); ?>">
116
- <span class="wp-media-buttons-icon dashicons dashicons-format-image"></span><?php _e( ' Add Slider', 'easingslider' ); ?>
117
- </a>
118
- <?php
119
-
120
- }
121
-
122
- /**
123
- * Renders a slider, returning the HTML
124
- *
125
- * @param array $atts The shortcode attributes
126
- * @return string
127
- */
128
- public function render( $atts = array() ) {
129
-
130
- // Allow extensions to modify
131
- $defaults = apply_filters( 'easingslider_shortcode_defaults', array( 'id' => false ) );
132
-
133
- // Combine shortcode attributes with defaults
134
- $atts = (object) shortcode_atts( $defaults, $atts );
135
-
136
- /**
137
- * Continue as normal if we have an ID.
138
- *
139
- * Otherwise, let's allow extensions to render sliders using their own method(s).
140
- */
141
- if ( ! empty( $atts->id ) ) {
142
-
143
- // Find the slider
144
- $slider = ES_Slider::find( $atts->id );
145
-
146
- // Display error message if no slider has been found
147
- if ( ! $slider ) {
148
- return sprintf( __( '<p><strong>The slider specified (ID #%s) could not be found.</strong></p>', 'easingslider' ), $atts->id );
149
- }
150
-
151
- // Render and return the slider
152
- return $slider->render();
153
-
154
- }
155
- else {
156
-
157
- // Start output buffer
158
- ob_start();
159
-
160
- // Trigger action for our extensions
161
- do_action( 'easingslider_display_shortcode', (array) $atts );
162
-
163
- // Return output buffer contents
164
- return ob_get_clean();
165
-
166
- }
167
-
168
- }
169
-
170
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-slider.php DELETED
@@ -1,823 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Defines our plugin public facing functionality
12
- *
13
- * @uses ES_Image_Resizer
14
- * @uses Easing_Slider
15
- * @author Matthew Ruddy
16
- */
17
- class ES_Slider {
18
-
19
- /**
20
- * The object post type
21
- *
22
- * @var string
23
- */
24
- public static $object_type = 'easingslider';
25
-
26
- /**
27
- * Constructor
28
- *
29
- * @return void
30
- */
31
- public function __construct() {
32
-
33
- // Set our default postdata and metadata respectively
34
- $this->set( $this->get_postdata_defaults() );
35
- $this->set( $this->get_metadata_defaults() );
36
-
37
- }
38
-
39
- /**
40
- * Sets an array of data on the slider
41
- *
42
- * @param array|object $data The array of data
43
- * @return ES_Slider
44
- */
45
- public function set( $data ) {
46
-
47
- foreach ( $data as $key => $value ) {
48
- $this->$key = $value;
49
- }
50
-
51
- return $this;
52
-
53
- }
54
-
55
- /**
56
- * Queries our sliders
57
- *
58
- * @param array $args Any arguments to be merged with the posts query
59
- * @return WP_Query
60
- */
61
- public static function query( $args = array() ) {
62
-
63
- $sliders = array();
64
-
65
- // Our default query arguments
66
- $defaults = array(
67
- 'post_status' => 'publish',
68
- 'post_type' => self::$object_type,
69
- 'orderby' => 'ID',
70
- 'order' => 'asc',
71
- 'posts_per_page' => -1
72
- );
73
-
74
- // Merge the query arguments
75
- $args = array_merge( (array) $defaults, (array) $args );
76
-
77
- // Execute the query
78
- $query = new WP_Query( $args );
79
-
80
- // Allow extensions to apply filters
81
- $query = apply_filters( 'easingslider_query_sliders', $query );
82
-
83
- return $query;
84
-
85
- }
86
-
87
- /**
88
- * Gets all of the sliders
89
- *
90
- * @return array
91
- */
92
- public static function all() {
93
-
94
- $sliders = array();
95
-
96
- // Query our sliders
97
- $query = self::query();
98
-
99
- // Loop through each post
100
- if ( $query->have_posts() ) {
101
- while( $query->have_posts() ) {
102
-
103
- $query->the_post();
104
-
105
- // Initiate a new slider
106
- $slider = new self;
107
-
108
- // Set our postdata and metadata
109
- $slider->set( get_object_vars( get_post( get_the_ID() ) ) );
110
- $slider->set( $slider->get_metadata() );
111
-
112
- // Add the slider to our sliders
113
- $sliders[] = $slider;
114
-
115
- }
116
-
117
- wp_reset_query();
118
- }
119
-
120
- // Allow extensions to apply filters
121
- $sliders = apply_filters( 'easingslider_all_sliders', $sliders );
122
-
123
- return $sliders;
124
-
125
- }
126
-
127
- /**
128
- * Finds a slider
129
- *
130
- * @param int $id The slider ID
131
- * @return ES_Slider
132
- */
133
- public static function find( $id ) {
134
-
135
- // Fetch our post
136
- $post = get_post( $id );
137
-
138
- // Bail if no post was found
139
- if ( ! $post ) {
140
- return false;
141
- }
142
-
143
- // Bail if not our post type
144
- if ( self::$object_type != $post->post_type ) {
145
- return false;
146
- }
147
-
148
- // Initiate a new slider
149
- $slider = new self;
150
-
151
- // Set our postdata and metadata
152
- $slider->set( get_object_vars( $post ) );
153
- $slider->set( $slider->get_metadata() );
154
-
155
- // Allow extensions to apply filters
156
- $slider = apply_filters( 'easingslider_find_slider', $slider );
157
-
158
- return $slider;
159
-
160
- }
161
-
162
- /**
163
- * Gets the total number slides that exist
164
- *
165
- * @param string $post_status The post status
166
- * @return object
167
- */
168
- public static function total( $post_status = 'publish' ) {
169
-
170
- $total_items = wp_count_posts( self::$object_type );
171
-
172
- return $total_items->$post_status;
173
-
174
- }
175
-
176
- /**
177
- * Creates a new slider instance
178
- *
179
- * @return ES_Slider
180
- */
181
- public static function create() {
182
-
183
- // Initiate a new slider
184
- $slider = new self;
185
-
186
- // Allow extensions to apply filters
187
- $slider = apply_filters( 'easingslider_create_slider', $slider );
188
-
189
- return $slider;
190
-
191
- }
192
-
193
- /**
194
- * Deletes a slider
195
- *
196
- * @param int $id The slider ID
197
- * @return void
198
- */
199
- public static function delete( $id ) {
200
-
201
- // Initiate a new slider
202
- $slider = new self;
203
-
204
- // Set the ID
205
- $slider->ID = $id;
206
-
207
- // Delete the post
208
- wp_delete_post( $id );
209
-
210
- // Allow extensions to do actions
211
- do_action( 'easingslider_delete_slider', $id );
212
-
213
- }
214
-
215
- /**
216
- * Saves a slider
217
- *
218
- * @return int|false
219
- */
220
- public function save() {
221
-
222
- // "Before" filter
223
- $slider = apply_filters( 'easingslider_pre_save_slider', $this );
224
-
225
- // Create or update the post
226
- if ( isset( $slider->ID ) ) {
227
- $slider->ID = wp_update_post( (array) $slider );
228
- }
229
- else {
230
- $slider->ID = wp_insert_post( (array) $slider );
231
- }
232
-
233
- // If an error has occurred, bail.
234
- if ( ! $slider->ID ) {
235
- return false;
236
- }
237
-
238
- // Create/update our metadata
239
- $slider->update_metadata();
240
-
241
- // Allow extensions to do actions
242
- do_action( 'easingslider_save_slider', $slider );
243
-
244
- return $slider;
245
-
246
- }
247
-
248
- /**
249
- * Renders the slider
250
- *
251
- * @return void
252
- */
253
- public function render() {
254
-
255
- // "Before" action
256
- $slider = apply_filters( 'easingslider_pre_display_slider', $this );
257
-
258
- // "Before" filter
259
- $html = apply_filters( 'easingslider_before_display_slider', '', $slider );
260
-
261
- // Start the output
262
- $html .= "<div class=\"". esc_attr( $slider->get_container_classes() ) ."\" data-options=\"". esc_attr( $slider->get_container_data() ) ."\" style=\"". esc_attr( $slider->get_container_styles() ) ."\">";
263
-
264
- // Inner "before" filter
265
- $html = apply_filters( 'easingslider_before_slider_content', $html, $slider );
266
-
267
- // Open the viewport
268
- $html .= "<div class=\"easingslider-viewport\" style=\"". esc_attr( $slider->get_viewport_styles() ) ."\">";
269
-
270
- // Output the slides
271
- foreach ( $slider->slides as $slide ) {
272
- $html .= $slider->render_slide_html( $slide );
273
- }
274
-
275
- // Close the viewport
276
- $html .= "</div>";
277
-
278
- // Output the arrows
279
- if ( $slider->navigation->arrows ) {
280
- $html .= $slider->render_arrows_html();
281
- }
282
-
283
- // Output the pagination
284
- if ( $slider->navigation->pagination ) {
285
- $html .= $slider->render_pagination_html();
286
- }
287
-
288
- // Inner "after" filter
289
- $html = apply_filters( 'easingslider_after_slider_content', $html, $slider );
290
-
291
- // End the output
292
- $html .= "</div>";
293
-
294
- // "After" filter
295
- $html = apply_filters( 'easingslider_after_display_slider', $html, $slider );
296
-
297
- // Allow extensions to do actions
298
- do_action( 'easingslider_render_slider', $slider );
299
-
300
- return $html;
301
-
302
- }
303
-
304
- /**
305
- * Registers all of our slider assets
306
- *
307
- * @return void
308
- */
309
- public function register_assets() {
310
-
311
- // Get our directories
312
- $css_dir = plugin_dir_url( Easing_Slider::$file ) . 'css';
313
- $js_dir = plugin_dir_url( Easing_Slider::$file ) . 'js';
314
-
315
- // Get file suffix
316
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
317
-
318
- // Register our stylesheets
319
- wp_register_style( 'easingslider', "{$css_dir}/easingslider{$suffix}.css", false, Easing_Slider::$version );
320
-
321
- // Register our javascripts
322
- wp_register_script( 'easingslider', "{$js_dir}/jquery.easingslider{$suffix}.js", array( 'jquery' ), Easing_Slider::$version );
323
-
324
- }
325
-
326
- /**
327
- * Enqueues all of our slider assets
328
- *
329
- * @return void
330
- */
331
- public function enqueue_assets() {
332
-
333
- // Get the settings
334
- $settings = get_option( 'easingslider_settings' );
335
-
336
- /**
337
- * If we've set the asset loading to "Optimized" and we haven't displayed a slider on this page, let's bail.
338
- * This prevents the assets from loading when they aren't needed.
339
- *
340
- * Otherwise, by default, assets will be loaded on every page ("Compatibility" mode).
341
- */
342
- if ( 'footer' == $settings->load_assets && ! did_action( 'easingslider_render_slider' ) ) {
343
- add_action( 'wp_footer', array( $this, 'enqueue_assets' ) );
344
- return;
345
- }
346
-
347
- // Enqueue our assets
348
- wp_enqueue_style( 'easingslider' );
349
- wp_enqueue_script( 'easingslider' );
350
-
351
- // Trigger action for our extensions
352
- do_action( 'easingslider_enqueue_assets' );
353
-
354
- }
355
-
356
- /**
357
- * Method for getting our post default keys and values
358
- *
359
- * @return array
360
- */
361
- protected function get_postdata_defaults() {
362
-
363
- $postdata_defaults = array(
364
- 'post_title' => '',
365
- 'post_status' => 'publish',
366
- 'post_type' => self::$object_type
367
- );
368
-
369
- return apply_filters( 'easingslider_postdata_defaults', $postdata_defaults );
370
-
371
- }
372
-
373
- /**
374
- * Method for getting our meta default keys and values
375
- *
376
- * @return array
377
- */
378
- protected function get_metadata_defaults() {
379
-
380
- // Our array of meta default data
381
- $metadata_defaults = array(
382
- 'slides' => array(),
383
- 'general' => (object) array(
384
- 'randomize' => false
385
- ),
386
- 'dimensions' => (object) array(
387
- 'width' => 640,
388
- 'height' => 400,
389
- 'responsive' => true,
390
- 'full_width' => false,
391
- 'image_resizing' => false,
392
- 'keep_ratio' => true,
393
- 'background_images' => false
394
- ),
395
- 'transitions' => (object) array(
396
- 'effect' => 'fade',
397
- 'duration' => 400
398
- ),
399
- 'navigation' => (object) array(
400
- 'arrows' => true,
401
- 'arrows_hover' => false,
402
- 'arrows_position' => 'inside',
403
- 'pagination' => true,
404
- 'pagination_hover' => false,
405
- 'pagination_position' => 'inside',
406
- 'pagination_location' => 'bottom-center'
407
- ),
408
- 'playback' => (object) array(
409
- 'enabled' => true,
410
- 'pause' => 4000
411
- )
412
- );
413
-
414
- return apply_filters( 'easingslider_metadata_defaults', $metadata_defaults );
415
-
416
- }
417
-
418
- /**
419
- * Method for getting our metadata
420
- *
421
- * @return array
422
- */
423
- protected function get_metadata() {
424
-
425
- $metadata = array();
426
-
427
- // Get the defaults
428
- $metadata_defaults = $this->get_metadata_defaults();
429
-
430
- // Loop through and merge in actual metadata
431
- foreach ( $metadata_defaults as $default_key => $default_metadata ) {
432
- $actual_metadata = get_post_meta( $this->ID, "_easingslider_{$default_key}", true );
433
-
434
- // Merge in the data
435
- if ( ! empty( $actual_metadata ) ) {
436
- $metadata[ $default_key ] = array_merge( (array) $default_metadata, (array) $actual_metadata );
437
-
438
- // Convert back to object if necessary
439
- if ( is_object( $default_metadata ) ) {
440
- $metadata[ $default_key ] = (object) $metadata[ $default_key ];
441
- }
442
- }
443
- }
444
-
445
- return $metadata;
446
-
447
- }
448
-
449
- /**
450
- * Method for updating our metadata
451
- *
452
- * @return void
453
- */
454
- protected function update_metadata() {
455
-
456
- $metadata = $this->get_metadata_defaults();
457
-
458
- // Loop through and attempt to get postmeta
459
- foreach ( $metadata as $key => $value ) {
460
- update_post_meta( $this->ID, "_easingslider_{$key}", $this->$key );
461
- }
462
-
463
- }
464
-
465
- /**
466
- * Returns the possible transitions
467
- *
468
- * @return array
469
- */
470
- public function get_transitions() {
471
-
472
- return apply_filters( 'easingslider_transitions', array(
473
- 'slide' => __( 'Slide', 'easingslider' ),
474
- 'fade' => __( 'Fade', 'easingslider' )
475
- ) );
476
-
477
- }
478
-
479
- /**
480
- * Returns HTML container data options attribute
481
- *
482
- * @return string
483
- */
484
- protected function get_container_data() {
485
-
486
- // Get metadata
487
- $metadata = $this->get_metadata();
488
-
489
- // Remove slides as we don't need them
490
- unset( $metadata['slides'] );
491
-
492
- return json_encode( apply_filters( 'easingslider_get_container_data', $metadata, $this ) );
493
-
494
- }
495
-
496
- /**
497
- * Returns HTML container classes
498
- *
499
- * @return string
500
- */
501
- protected function get_container_classes() {
502
-
503
- $classes = "easingslider easingslider-{$this->ID} no-js use-{$this->transitions->effect}";
504
-
505
- return apply_filters( 'easingslider_get_container_classes', $classes, $this );
506
-
507
- }
508
-
509
- /**
510
- * Returns HTML container styling
511
- *
512
- * @return string
513
- */
514
- protected function get_container_styles() {
515
-
516
- // Handle responsive and fixed dimensions separately
517
- if ( $this->dimensions->responsive ) {
518
-
519
- // Handle full width if enabled or disabled
520
- if ( $this->dimensions->full_width ) {
521
- $styles = "max-width: 100% !important; ";
522
- }
523
- else {
524
- $styles = "max-width: {$this->dimensions->width}px !important; ";
525
- }
526
-
527
- // Limit the max height
528
- $styles .= "max-height: {$this->dimensions->height}px !important;";
529
-
530
- }
531
- else {
532
-
533
- // Add fixed dimensions for non-responsive
534
- $styles = "width: {$this->dimensions->width}px !important; height: {$this->dimensions->height}px !important;";
535
-
536
- }
537
-
538
- return apply_filters( 'easingslider_get_container_styles', $styles, $this );
539
-
540
- }
541
-
542
- /**
543
- * Returns HTML viewport styling
544
- *
545
- * @return string
546
- */
547
- protected function get_viewport_styles() {
548
-
549
- // Set the height
550
- $styles = "height: {$this->dimensions->height}px;";
551
-
552
- // Limit max height when responsive
553
- if ( $this->dimensions->responsive ) {
554
- $styles .= "max-height: {$this->dimensions->height}px;";
555
- }
556
-
557
- return apply_filters( 'easingslider_get_viewport_styles', $styles, $this );
558
-
559
- }
560
-
561
- /**
562
- * Renders HTML for a slide
563
- *
564
- * @param object $slide The slide object
565
- * @return string
566
- */
567
- protected function render_slide_html( $slide ) {
568
-
569
- // Animation duration styling. This is horrible, but necessary to have varied animation durations
570
- $animation_duration = "-webkit-animation-duration: {$this->transitions->duration}ms; -moz-animation-duration: {$this->transitions->duration}ms; -ms-animation-duration: {$this->transitions->duration}ms; -o-animation-duration: {$this->transitions->duration}ms; animation-duration: {$this->transitions->duration}ms;";
571
-
572
- /**
573
- * We initially "display: none" our slides to prevent a brief flash of unstyled HTML when loading the CSS & Javascript in the footer.
574
- *
575
- * The Javascript will set slides to "display: block".
576
- */
577
- $html = "<div class=\"easingslider-slide easingslider-slide-{$slide->id} easingslider-{$slide->type}-slide\" style=\"{$animation_duration}\">";
578
-
579
- $html = apply_filters( 'easingslider_before_display_slide', $html, $slide, $this );
580
-
581
- $html = apply_filters( "easingslider_display_{$slide->type}_slide", $html, $slide, $this );
582
-
583
- $html = apply_filters( 'easingslider_after_display_slide', $html, $slide, $this );
584
-
585
- $html .= "</div>";
586
-
587
- return apply_filters( 'easingslider_get_html_slide', $html, $slide, $this );
588
-
589
- }
590
-
591
- /**
592
- * Renders HTML for the arrows
593
- *
594
- * @return string
595
- */
596
- protected function render_arrows_html() {
597
-
598
- $html = "<div class=\"easingslider-arrows easingslider-next {$this->navigation->arrows_position}\" style=\"display: none;\"></div>";
599
- $html .= "<div class=\"easingslider-arrows easingslider-prev {$this->navigation->arrows_position}\" style=\"display: none;\"></div>";
600
-
601
- return apply_filters( 'easingslider_get_html_arrows', $html, $this );
602
-
603
- }
604
-
605
- /**
606
- * Renders HTML for the pagination
607
- *
608
- * @return string
609
- */
610
- protected function render_pagination_html() {
611
-
612
- $html = "<div class=\"easingslider-pagination {$this->navigation->pagination_position} {$this->navigation->pagination_location}\" style=\"display: none;\">";
613
-
614
- // Create an icon for each slide
615
- foreach ( $this->slides as $slide ) {
616
- $html .= "<div class=\"easingslider-icon\"></div>";
617
- }
618
-
619
- $html .= "</div>";
620
-
621
- return apply_filters( 'easingslider_get_html_pagination', $html, $this );
622
-
623
- }
624
-
625
- /**
626
- * Calculates the aspect ratio
627
- *
628
- * @return string
629
- */
630
- protected function calculate_aspect_ratio() {
631
-
632
- $aspect_ratio = ( $this->dimensions->height / $this->dimensions->width );
633
-
634
- return $aspect_ratio;
635
-
636
- }
637
-
638
- /**
639
- * Randomizes the slides if set to do so
640
- *
641
- * @param ES_Slider $slider The slider object
642
- * @return ES_Slider
643
- */
644
- public function maybe_randomize( $slider ) {
645
-
646
- if ( $slider->general->randomize ) {
647
- shuffle( $slider->slides );
648
- }
649
-
650
- return $slider;
651
-
652
- }
653
-
654
- /**
655
- * Sets a default "(no title)" if no slider title was provided
656
- *
657
- * @param ES_Slider $slider The slider object
658
- * @return ES_Slider
659
- */
660
- public function no_title( $slider ) {
661
-
662
- if ( empty( $slider->post_title ) ) {
663
- $slider->post_title = __( '(no title)', 'easingslider' );
664
- }
665
-
666
- return $slider;
667
-
668
- }
669
-
670
- /**
671
- * Removes unneccessary attributes from HTML data
672
- *
673
- * @param object $data The slider data
674
- * @return object
675
- */
676
- public function cleanup_data( $data ) {
677
-
678
- unset( $data['slides'] );
679
-
680
- return $data;
681
-
682
- }
683
-
684
- /**
685
- * Adds "<noscript>" styling to slider for when Javascript is disabled
686
- *
687
- * @param string $html The slider HTML
688
- * @param object $slider The slider object
689
- * @return string
690
- */
691
- public function no_script( $html, $slider ) {
692
-
693
- // Add the "<noscript">
694
- $html .= "<noscript>";
695
- $html .= "<style type=\"text/css\">";
696
- $html .= ".easingslider-{$slider->ID} .easingslider-preload { ";
697
- $html .= "display: none; ";
698
- $html .= "} ";
699
-
700
- $html .= ".easingslider-{$slider->ID} .easingslider-slide { ";
701
- $html .= "display: none; ";
702
- $html .= "} ";
703
-
704
- $html .= ".easingslider-{$slider->ID} .easingslider-slide-1 { ";
705
- $html .= "display: block !important; ";
706
- $html .= "}";
707
- $html .= "</style>";
708
- $html .= "</noscript>";
709
-
710
- return $html;
711
-
712
- }
713
-
714
- /**
715
- * Adds the HTML for the preloader
716
- *
717
- * @param string $html The slider HTML
718
- * @param object $slider The slider object
719
- * @return string
720
- */
721
- public function add_preload( $html, $slider ) {
722
-
723
- // Add the HTML
724
- $html .= "<div class=\"easingslider-preload\"></div>";
725
-
726
- return $html;
727
-
728
- }
729
-
730
- /**
731
- * Adds the HTML for an image
732
- *
733
- * @param string $html The slider HTML
734
- * @param object $slide The slide object
735
- * @param object $slider The slider object
736
- * @return string
737
- */
738
- public function add_image( $html, $slide, $slider ) {
739
-
740
- // Get the image URL
741
- $image_url = ( $slide->attachment_id ) ? wp_get_attachment_url( $slide->attachment_id ) : $slide->url;
742
-
743
- // Filter for modifying the image URL (needed for resizing, etc).
744
- $image_url = apply_filters( 'easingslider_modify_image_url', $image_url, $slide, $slider );
745
-
746
- // Add the HTML
747
- $html .= "<img src=\"{$image_url}\" title=\"{$slide->title}\" alt=\"{$slide->alt}\" class=\"easingslider-image\" />";
748
-
749
- return $html;
750
-
751
- }
752
-
753
- /**
754
- * Resizes an image
755
- *
756
- * @param string $image_url The image URL
757
- * @param object $slide The slide object
758
- * @param object $slider The slider object
759
- * @return string
760
- */
761
- public function resize_image( $image_url, $slide, $slider ) {
762
-
763
- // Resize the image if enabled
764
- if ( $slider->dimensions->image_resizing ) {
765
-
766
- // Initiate image resizer
767
- $image_resizer = new ES_Image_Resizer();
768
-
769
- // Resize the image
770
- $image_url = $image_resizer->resized_image_url( $image_url, $slider->dimensions->width, $slider->dimensions->height );
771
-
772
- }
773
-
774
- return $image_url;
775
-
776
- }
777
-
778
- /**
779
- * Opens a link
780
- *
781
- * @param string $html The slider HTML
782
- * @param object $slide The slide object
783
- * @param object $slider The slider object
784
- * @return string
785
- */
786
- public function open_link( $html, $slide, $slider ) {
787
-
788
- if ( ! empty( $slide->link ) && 'none' != $slide->link ) {
789
-
790
- // The link attributes string
791
- $attributes_string = "href=\"{$slide->linkUrl}\" target=\"{$slide->linkTargetBlank}\" class=\"easingslider-link\"";
792
-
793
- // Apply filters to the string
794
- $attributes_string = apply_filters( 'easingslider_open_link_html_attributes', $attributes_string, $slide, $slider );
795
-
796
- // Add the HTML
797
- $html .= "<a {$attributes_string}>";
798
-
799
- }
800
-
801
- return $html;
802
-
803
- }
804
-
805
- /**
806
- * Closes a link
807
- *
808
- * @param string $html The slider HTML
809
- * @param object $slide The slide object
810
- * @param object $slider The slider object
811
- * @return string
812
- */
813
- public function close_link( $html, $slide, $slider ) {
814
-
815
- if ( ! empty( $slide->link ) && 'none' != $slide->link ) {
816
- $html .= "</a>";
817
- }
818
-
819
- return $html;
820
-
821
- }
822
-
823
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-sliders-list-table.php DELETED
@@ -1,424 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Ensure WP_List_Table class has been loaded
12
- */
13
- if ( ! class_exists( 'WP_List_Table' ) ) {
14
- require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
15
- }
16
-
17
- /**
18
- * Our extension for WP_List_Table for listing sliders
19
- *
20
- * @uses ES_Slider
21
- * @author Matthew Ruddy
22
- */
23
- class ES_Sliders_List_Table extends WP_List_Table {
24
-
25
- /**
26
- * Constructor
27
- *
28
- * @return void
29
- */
30
- public function __construct() {
31
-
32
- parent::__construct( array(
33
- 'singular' => 'slider',
34
- 'plural' => 'sliders',
35
- 'ajax' => false
36
- ));
37
-
38
- }
39
-
40
- /**
41
- * Get our list table columns
42
- *
43
- * @return array
44
- */
45
- public function get_columns() {
46
-
47
- // Set our columns
48
- $columns = array(
49
- 'cb' => '<input type="checkbox" />',
50
- 'ID' => __( 'ID', 'easingslider' ),
51
- 'post_title' => __( 'Title', 'easingslider' ),
52
- 'post_author' => __( 'Author', 'easingslider' ),
53
- 'post_date' => __( 'Date', 'easingslider' ),
54
- 'shortcode' => __( 'Shortcode', 'easingslider' ),
55
- 'template_function' => __( 'Template Function', 'easingslider' )
56
- );
57
-
58
- return apply_filters( 'easingslider_sliders_list_table_columns', $columns );
59
-
60
- }
61
-
62
- /**
63
- * Get the columns that have been hidden by the current user
64
- *
65
- * @return array
66
- */
67
- public function get_hidden_columns() {
68
-
69
- // Get the current screen
70
- $current_screen = get_current_screen();
71
-
72
- // Get the hidden columns
73
- $hidden_columns = (array) get_user_option( "manage{$current_screen->id}columnshidden" );
74
-
75
- return $hidden_columns;
76
-
77
- }
78
-
79
- /**
80
- * Decide which columns to activate the sorting functionality on
81
- *
82
- * @return array
83
- */
84
- public function get_sortable_columns() {
85
-
86
- // Set our sortable columns
87
- $sortable_columns = array(
88
- 'ID' => array( 'ID', false ),
89
- 'post_title' => array( 'post_title', false ),
90
- 'post_author' => array( 'post_author', false ),
91
- 'post_date' => array( 'post_date', false )
92
- );
93
-
94
- return apply_filters( 'easingslider_sliders_list_table_sortable_columns', $sortable_columns );
95
-
96
- }
97
-
98
- /**
99
- * Gets the number of list items per page
100
- *
101
- * @return int
102
- */
103
- public function get_per_page() {
104
-
105
- // Get the current page
106
- $current_screen = get_current_screen();
107
-
108
- // Get the number of items per page
109
- $per_page = (int) get_user_option( 'sliders_per_page' );
110
-
111
- // Return default if false
112
- if ( ! $per_page ) {
113
- return 20;
114
- }
115
-
116
- return $per_page;
117
-
118
- }
119
-
120
- /**
121
- * Prepare our list table items
122
- *
123
- * @return void
124
- */
125
- public function prepare_items() {
126
-
127
- // Process any outstanding actions
128
- $this->process_action();
129
-
130
- // Get our variables
131
- $columns = $this->get_columns();
132
- $hidden_columns = $this->get_hidden_columns();
133
- $sortable_columns = $this->get_sortable_columns();
134
-
135
- // Get our pagination variables
136
- $per_page = $this->get_per_page();
137
- $current_page = $this->get_pagenum();
138
-
139
- // Our posts query arguments
140
- $query_args = array(
141
- 'posts_per_page' => $per_page,
142
- );
143
-
144
- // If paginated, ammend our query
145
- if ( isset( $_GET['paged'] ) ) {
146
- $query_args['paged'] = sanitize_key( $_GET['paged'] );
147
- }
148
-
149
- // If searching, ammend our query
150
- if ( isset( $_GET['s'] ) ) {
151
- $query_args['s'] = sanitize_title( $_GET['s'] );
152
- }
153
-
154
- // Add sort queries
155
- $query_args['orderby'] = ( ! empty( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : 'ID';
156
- $query_args['order'] = ( ! empty( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : 'asc';
157
-
158
- // Query our sliders
159
- $query = ES_Slider::query( $query_args );
160
-
161
- // Set our pagination arguments
162
- $this->set_pagination_args( array(
163
- 'total_items' => $query->found_posts,
164
- 'per_page' => $per_page
165
- ) );
166
-
167
- // Set our column headers
168
- $this->_column_headers = array( $columns, $hidden_columns, $sortable_columns );
169
-
170
- // Assign our table items
171
- $this->items = $query->posts;
172
-
173
- }
174
-
175
- /**
176
- * Our bulk actions for this list
177
- *
178
- * @return array
179
- */
180
- public function get_bulk_actions() {
181
-
182
- $actions = array(
183
- 'duplicate' => __( 'Duplicate', 'easingslider' ),
184
- 'delete' => __( 'Delete', 'easingslider' )
185
- );
186
-
187
- return apply_filters( 'easingslider_sliders_list_table_bulk_actions', $actions );
188
-
189
- }
190
-
191
- /**
192
- * Processes an action, or a bulk action if appropriate.
193
- *
194
- * @return void
195
- */
196
- public function process_action() {
197
-
198
- // Get the current action
199
- $action = $this->current_action();
200
-
201
- // Generate the method string
202
- $method = "process_{$action}_action";
203
-
204
- // Bail if this method doesn't exist
205
- if ( ! method_exists( $this, $method ) ) {
206
- return;
207
- }
208
-
209
- // Do either a single action or a bulk action
210
- if ( isset( $_GET['id'] ) ) {
211
-
212
- // Bail if nonce is invalid
213
- if ( ! check_admin_referer( $action ) ) {
214
- return;
215
- }
216
-
217
- // Call the action
218
- call_user_func( array( $this, $method ), sanitize_key( $_GET['id'] ) );
219
-
220
- }
221
- else if ( isset( $_GET['ids'] ) ) {
222
-
223
- // Bail if nonce is invalid
224
- if ( ! check_admin_referer( "bulk-{$this->_args['plural']}" ) ) {
225
- return;
226
- }
227
-
228
- // Sanatize IDs
229
- $ids = array_map( 'sanitize_key', $_GET['ids'] );
230
-
231
- // Call the action for each ID
232
- array_walk( $_GET['ids'], array( $this, $method ) );
233
-
234
- }
235
-
236
- }
237
-
238
- /**
239
- * Processes a duplicate action
240
- *
241
- * @param int $id The slider ID
242
- * @return void
243
- */
244
- public function process_duplicate_action( $id ) {
245
-
246
- // Get the slider
247
- $slider = ES_Slider::find( $id );
248
-
249
- // Unset the slider ID
250
- unset( $slider->ID );
251
-
252
- // Append "- Copy" to the slider title
253
- $slider->post_title = sprintf( __( "%s - Copy", 'easingslider' ), $slider->post_title );
254
-
255
- // Save the slider, thus creating a new one as no ID is present.
256
- $slider->save();
257
-
258
- }
259
-
260
- /**
261
- * Processes a delete action
262
- *
263
- * @param int $id The slider ID
264
- * @return void
265
- */
266
- public function process_delete_action( $id ) {
267
-
268
- // Delete the slider
269
- ES_Slider::delete( $id );
270
-
271
- }
272
-
273
- /**
274
- * Our checkbox column method
275
- *
276
- * @param object $item Our column item
277
- * @return string
278
- */
279
- public function column_cb( $item ) {
280
-
281
- return sprintf( '<input type="checkbox" name="ids[]" value="%s" />', $item->ID );
282
-
283
- }
284
-
285
- /**
286
- * Our post title column method
287
- *
288
- * @param object $item Our column item
289
- * @return string
290
- */
291
- public function column_post_title( $item ) {
292
-
293
- // Get & escape the page
294
- $page = esc_attr( $_GET['page'] );
295
-
296
- // Our title string
297
- $title = sprintf( '<strong><a class="row-title" href="?page=%s&edit=%s">%s</a></strong>', $page, $item->ID, $item->post_title );
298
-
299
- // Add nonces to action URLs
300
- $duplicate_link = wp_nonce_url( "?page={$page}&action=duplicate&id={$item->ID}", 'duplicate' );
301
- $delete_link = wp_nonce_url( "?page={$page}&action=delete&id={$item->ID}", 'delete' );
302
-
303
- // Our array of actions
304
- $actions = array(
305
- 'edit' => sprintf( '<a href="?page=%s&edit=%s">Edit</a>', $page, $item->ID ),
306
- 'duplicate' => sprintf( '<a href="%s">Duplicate</a>', $duplicate_link ),
307
- 'delete' => sprintf( '<a href="%s">Delete</a>', $delete_link ),
308
- );
309
-
310
- return sprintf( '%1$s %2$s', $title, $this->row_actions( $actions ) );
311
-
312
- }
313
-
314
- /**
315
- * Our post author column method
316
- *
317
- * @param object $item Our column item
318
- * @return string
319
- */
320
- public function column_post_author( $item ) {
321
-
322
- // Get & escape the page
323
- $page = esc_attr( $_GET['page'] );
324
-
325
- $author = sprintf(
326
- '<a href="%s">%s</a>',
327
- esc_url( add_query_arg( array( 'page' => $page, 'author' => get_the_author_meta( 'ID', $item->post_author ) ) ) ),
328
- get_the_author_meta( 'display_name', $item->post_author )
329
- );
330
-
331
- return sprintf( '%1$s', $author );
332
-
333
- }
334
-
335
- /**
336
- * Our post date column method
337
- *
338
- * @param object $item Our column item
339
- * @return string
340
- */
341
- public function column_post_date( $item ) {
342
-
343
- // Get the time strings
344
- $post_time = get_post_time( 'G', true, $item->ID );
345
- $abbr_time = get_post_time( 'Y/m/d g:i:s A', true, $item->ID );
346
-
347
- // Calculate the time difference from now
348
- $time_diff = time() - $post_time;
349
-
350
- // Get the appropriate time string
351
- if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
352
-
353
- // Return a pretty text string
354
- $date = sprintf( __( '%s ago', 'easingslider' ), human_time_diff( $post_time ) );
355
-
356
- }
357
- else {
358
-
359
- // Return a date, month and year string
360
- $date = mysql2date( __( 'Y/m/d' ), $item->post_date );
361
-
362
- }
363
-
364
- return sprintf( '<abbr title="%1$s">%2$s</abbr><br />%3$s', $abbr_time, $date, __( 'Published', 'easingslider' ) );
365
-
366
- }
367
-
368
- /**
369
- * Our shortcode column method
370
- *
371
- * @param object $item Our column item
372
- * @return string
373
- */
374
- public function column_shortcode( $item ) {
375
-
376
- $shortcode = sprintf( esc_html( '[easingslider id="%d"]' ), $item->ID );
377
-
378
- return sprintf( '<input type="text" readonly="readonly" value="%s" />', $shortcode );
379
-
380
- }
381
-
382
- /**
383
- * Our template function column method
384
- *
385
- * @param object $item Our column item
386
- * @return string
387
- */
388
- public function column_template_function( $item ) {
389
-
390
- $template_function = sprintf( esc_html( '<?php if ( function_exists( \'easingslider\' ) ) { easingslider( %d ); } ?>' ), $item->ID );
391
-
392
- return sprintf( '<input type="text" readonly="readonly" value="%s" />', $template_function );
393
-
394
- }
395
-
396
- /**
397
- * Our default column methods
398
- *
399
- * @param array $item Our column item
400
- * @param string $column_name The column name
401
- * @return string
402
- */
403
- public function column_default( $item, $column_name ) {
404
-
405
- switch ( $column_name ) {
406
- default:
407
- return $item->$column_name;
408
- }
409
-
410
- }
411
-
412
- /**
413
- * Our custom "No items" text
414
- *
415
- * @return void
416
- */
417
- public function no_items() {
418
-
419
- // That's all folks!
420
- _e( 'No sliders found.', 'easingslider' );
421
-
422
- }
423
-
424
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-update-manager.php DELETED
@@ -1,473 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * This code is for debugging purposes.
12
- * Uncomment this line to force WordPress to check for plugin updates on every page load.
13
- */
14
- // set_site_transient( 'update_plugins', null );
15
-
16
- /**
17
- * This class handles all the update-related stuff for extensions, including adding a license section to the "Licenses" settings tab.
18
- *
19
- * @author Matthew Ruddy
20
- */
21
- class ES_Update_Manager {
22
-
23
- /**
24
- * Plugin name
25
- *
26
- * @var string
27
- */
28
- protected $name;
29
-
30
- /**
31
- * Plugin file
32
- *
33
- * @var string
34
- */
35
- protected $file;
36
-
37
- /**
38
- * Plugin slug
39
- *
40
- * @var string
41
- */
42
- protected $slug;
43
-
44
- /**
45
- * Plugin version
46
- *
47
- * @var int
48
- */
49
- protected $version;
50
-
51
- /**
52
- * License key
53
- *
54
- * @var string
55
- */
56
- protected $key;
57
-
58
- /**
59
- * Our API Url
60
- *
61
- * @var string
62
- */
63
- public $api_url = 'http://easingslider.com/api/';
64
-
65
- /**
66
- * Transient expiry time (default 6 hours)
67
- *
68
- * @var int
69
- */
70
- public $transient_expiry = 21600;
71
-
72
- /**
73
- * Constructor
74
- *
75
- * @param array $name The plugin name
76
- * @param string $file The plugin file
77
- * @param int $version The plugin version
78
- * @return void
79
- */
80
- public function __construct( $name, $file, $version ) {
81
-
82
- // Establish variables
83
- $this->name = $name;
84
- $this->file = $file;
85
- $this->slug = basename( $file, '.php' );
86
- $this->version = $version;
87
-
88
- // Filter variables
89
- $this->api_url = apply_filters( 'easingslider_update_manager_api_url', $this->api_url );
90
- $this->transient_expiry = apply_filters( 'easingslider_update_manager_transient_expiry', $this->transient_expiry );
91
-
92
- // Set the license key
93
- $this->set_key();
94
-
95
- // Define hooks for this license
96
- $this->define_hooks();
97
-
98
- }
99
-
100
- /**
101
- * Sets the license key
102
- *
103
- * @return void
104
- */
105
- protected function set_key() {
106
-
107
- // Check post request for key, otherwise get it from the setting.
108
- if ( ! empty( $_POST['settings'] ) && isset( $_POST['settings']["{$this->slug}_license_key"] ) ) {
109
-
110
- // Set the license key from our request
111
- $this->key = $_POST['settings']["{$this->slug}_license_key"];
112
-
113
- }
114
- else {
115
-
116
- // Get the settings
117
- $settings = get_option( 'easingslider_settings' );
118
-
119
- // Get the license key index
120
- $key_index = "{$this->slug}_license_key";
121
-
122
- // Set the license key if it exists
123
- if ( isset( $settings->{$key_index} ) ) {
124
- $this->key = $settings->{$key_index};
125
- }
126
-
127
- }
128
-
129
- }
130
-
131
- /**
132
- * Define hooks for this license
133
- *
134
- * @return void
135
- */
136
- protected function define_hooks() {
137
-
138
- add_action( 'easingslider_do_settings_actions', array( $this, 'attempt_deactivation' ) );
139
- add_action( 'easingslider_do_settings_actions', array( $this, 'attempt_registration' ) );
140
- add_action( 'easingslider_print_license_fields', array( $this, 'display_license_field' ) );
141
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'modify_updates_transient' ) );
142
- add_filter( 'plugins_api', array( $this, 'get_update_info' ), 10, 3 );
143
-
144
- }
145
-
146
- /**
147
- * Registers the license key to the current site
148
- *
149
- * @return boolean|string
150
- */
151
- public function register() {
152
-
153
- // Make the validation request
154
- $request = wp_remote_post( $this->api_url, array(
155
- 'timeout' => 10,
156
- 'body' => array(
157
- 'action' => 'register_license',
158
- 'key' => $this->key,
159
- 'slug' => $this->slug,
160
- 'url' => home_url(),
161
- 'version' => $this->version
162
- )
163
- ) );
164
-
165
- // Bail if WordPress error was received (HTTP API may have failed or may not have access required)
166
- if ( is_wp_error( $request ) ) {
167
-
168
- return $request->get_error_message();
169
-
170
- }
171
-
172
- // Get the response headers
173
- $headers = (object) wp_remote_retrieve_headers( $request );
174
-
175
- // Get the response body
176
- $response = json_decode( wp_remote_retrieve_body( $request ) );
177
-
178
- // Bail if no response was received (service may temporarily be offline)
179
- if ( ! isset( $response->response ) ) {
180
-
181
- return __( 'The license key registration service is temporarily unavailable. Please try again later.', 'easingslider' );
182
-
183
- }
184
-
185
- // If registration was a success, return true.
186
- if ( 200 == $headers->status ) {
187
-
188
- // Flag the license as valid
189
- update_option( "{$this->slug}_license_is_valid", true );
190
-
191
- return true;
192
-
193
- }
194
-
195
- return $response->response;
196
-
197
- }
198
-
199
- /**
200
- * Deactivates the license registration for the current site
201
- *
202
- * @return boolean|string
203
- */
204
- public function deactivate() {
205
-
206
- // Make the validation request
207
- $request = wp_remote_post( $this->api_url, array(
208
- 'timeout' => 10,
209
- 'body' => array(
210
- 'action' => 'deactivate_license',
211
- 'key' => $this->key,
212
- 'slug' => $this->slug,
213
- 'url' => home_url(),
214
- 'version' => $this->version
215
- )
216
- ) );
217
-
218
- // Bail if WordPress error was received (HTTP API may have failed or may not have access required)
219
- if ( is_wp_error( $request ) ) {
220
-
221
- return $request->get_error_message();
222
-
223
- }
224
-
225
- // Get the response headers
226
- $headers = (object) wp_remote_retrieve_headers( $request );
227
-
228
- // If license was successfully deactivated, return true.
229
- if ( 204 == $headers->status ) {
230
-
231
- // Delete the license validation flag
232
- delete_option( "{$this->slug}_license_is_valid" );
233
-
234
- return true;
235
-
236
- }
237
-
238
- // If we've gotten here, there's been an error. Tell the user.
239
- return __( 'Your license could not be deactivated. Please contact support to have it deactivated correctly.', 'easingslider' );
240
-
241
- }
242
-
243
- /**
244
- * Get plugin updates, requesting to server if required.
245
- *
246
- * @return array|false
247
- */
248
- public function get_updates() {
249
-
250
- // Make the request
251
- $request = wp_remote_post( $this->api_url, array(
252
- 'timeout' => 10,
253
- 'body' => array(
254
- 'action' => 'get_updates',
255
- 'key' => $this->key,
256
- 'slug' => $this->slug,
257
- 'url' => home_url(),
258
- 'version' => $this->version
259
- )
260
- ) );
261
-
262
- // Get the response headers
263
- $headers = (object) wp_remote_retrieve_headers( $request );
264
-
265
- // Get the response body
266
- $response = json_decode( wp_remote_retrieve_body( $request ) );
267
-
268
- // Bail if no response was received (service may temporarily be offline)
269
- if ( ! isset( $response->response ) ) {
270
- return false;
271
- }
272
-
273
- // If the status indicates the request wasn't a success, bail and flag invalid license key.
274
- if ( 200 != $headers->status ) {
275
-
276
- // Delete the license validation flag
277
- delete_option( "{$this->slug}_license_is_valid" );
278
-
279
- return false;
280
-
281
- }
282
-
283
- // Return the updates
284
- return $response->response;
285
-
286
- }
287
-
288
- /**
289
- * Attempts to register the license key to this site
290
- *
291
- * @return void
292
- */
293
- public function attempt_registration() {
294
-
295
- // Bail if we have no license key
296
- if ( empty( $this->key ) ) {
297
- return;
298
- }
299
-
300
- // Bail if not registering this license
301
- if ( ! isset( $_POST["register-{$this->slug}"] ) OR ! isset( $_POST['save'] ) ) {
302
- return;
303
- }
304
-
305
- // Check security nonce
306
- if ( ! check_admin_referer( 'save' ) ) {
307
- return;
308
- }
309
-
310
- // Attempt to register the license
311
- $response = $this->register();
312
-
313
- // Handle response
314
- if ( true === $response ) {
315
-
316
- // Tell the user the license was registered successfully.
317
- easingslider_show_notice( sprintf( __( '"%s" License has been registered successfully.', 'easingslider' ), $this->name ), 'updated notice' );
318
-
319
- }
320
- else {
321
-
322
- // Tell the user we failed to register the license
323
- easingslider_show_notice( $response, 'error' );
324
-
325
- }
326
-
327
- }
328
-
329
- /**
330
- * Attempts to deactive the license key for this site
331
- *
332
- * @return void
333
- */
334
- public function attempt_deactivation() {
335
-
336
- // Bail if not deactivating this license
337
- if ( ! isset( $_POST["deactivate-{$this->slug}"] ) ) {
338
- return;
339
- }
340
-
341
- // Check security nonce
342
- if ( ! check_admin_referer( 'save' ) ) {
343
- return;
344
- }
345
-
346
- // Attempt to deactivate the license
347
- $response = $this->deactivate();
348
-
349
- // Handle response
350
- if ( true === $response ) {
351
-
352
- // Tell the user the license was registered successfully.
353
- easingslider_show_notice( sprintf( __( '"%s" License has been deactivated successfully.', 'easingslider' ), $this->name ), 'updated notice' );
354
-
355
- }
356
- else {
357
-
358
- // Tell the user we failed to deactivate the license
359
- easingslider_show_notice( $response, 'error' );
360
-
361
- }
362
-
363
- }
364
-
365
- /**
366
- * Displays the license settings field
367
- *
368
- * @return void
369
- */
370
- public function display_license_field() {
371
-
372
- // Get the settings
373
- $settings = get_option( 'easingslider_settings' );
374
-
375
- // Get license validation flag
376
- $is_valid = get_option( "{$this->slug}_license_is_valid" );
377
-
378
- // Get the license key index
379
- $key_index = "{$this->slug}_license_key";
380
-
381
- // Display the field
382
- ?>
383
- <tr>
384
- <th scope="row">
385
- <label for="<?php echo esc_attr( $this->slug ); ?>">
386
- <?php printf( __( '"%s" License Key', 'easingslider' ), $this->name ); ?>
387
- </label>
388
- </th>
389
- <td>
390
- <input type="hidden" name="register-<?php echo esc_attr( $this->slug ); ?>" value="true">
391
- <span class="<?php if ( $is_valid ) { echo 'valid-license'; } ?>">
392
- <input type="text" name="<?php echo "settings[{$key_index}]"; ?>" class="regular-text" value="<?php if ( isset( $settings->{$key_index} ) ) { echo esc_attr( $settings->{$key_index} ); } ?>">
393
- </span>
394
- <?php if ( $is_valid ) : ?>
395
- <input type="submit" class="button button-secondary" id="deactivate" name="deactivate-<?php echo esc_attr( $this->slug ); ?>" value="<?php _e( 'Deactivate', 'easingslider' ); ?>">
396
- <?php endif; ?>
397
- </td>
398
- </tr>
399
- <?php
400
-
401
- }
402
-
403
- /**
404
- * Displays plugin update information on the WordPress Plugins page
405
- *
406
- * @param object $res
407
- * @param string $action The action occurring
408
- * @param object $args The arguments
409
- * @return object
410
- */
411
- public function get_update_info( $res, $action, $args ) {
412
-
413
- // Return the plugin information object
414
- if ( isset( $args->slug ) && $args->slug == $this->slug ) {
415
-
416
- // Get available update info stored in database
417
- $updates = $this->get_updates();
418
-
419
- // Ensure sections are an array (avoids errors)
420
- $updates->information->sections = (array) $updates->information->sections;
421
-
422
- // Return information (if it exists)
423
- if ( $updates->information ) {
424
- return $updates->information;
425
- }
426
-
427
- }
428
-
429
- return $res;
430
-
431
- }
432
-
433
- /**
434
- * Modifies the WordPress updates transient to include our update information
435
- *
436
- * @param object $checked_data The data of checked plugin updates
437
- * @return object
438
- */
439
- public function modify_updates_transient( $checked_data ) {
440
-
441
- // Get current updates
442
- $updates = $this->get_updates();
443
-
444
- // Bail if false returned
445
- if ( ! $updates ) {
446
- return $checked_data;
447
- }
448
-
449
- // Add our update information
450
- if ( empty( $checked_data->response ) OR empty ( $checked_data->response[ $this->slug ] ) ) {
451
-
452
- // Remove plugin's API information (not need for this).
453
- unset( $updates->information );
454
-
455
- // Bail if we are using the current version
456
- if ( version_compare( $this->version, $updates->new_version, '<' ) ) {
457
-
458
- // Add the update information
459
- $checked_data->response[ $this->file ] = $updates;
460
-
461
- }
462
-
463
- // Set last checked timestamp and version
464
- $checked_data->last_checked = time();
465
- $checked_data->checked[ $this->file ] = $this->version;
466
-
467
- }
468
-
469
- return $checked_data;
470
-
471
- }
472
-
473
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-welcome-pages.php DELETED
@@ -1,205 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Defines our "Welcome" page functionality
12
- *
13
- * @uses Easing_Slider
14
- * @author Matthew Ruddy
15
- */
16
- class ES_Welcome_Pages {
17
-
18
- /**
19
- * Adds our "Welcome" page(s) to the dashboard
20
- *
21
- * @return void
22
- */
23
- public function add_dashboard_pages() {
24
-
25
- // "About" page
26
- $hooks[] = add_dashboard_page(
27
- __( 'Welcome to Easing Slider', 'easingslider' ),
28
- __( 'Welcome to Easing Slider', 'easingslider' ),
29
- 'manage_options',
30
- 'easingslider-about',
31
- array( $this, 'display_view' )
32
- );
33
-
34
- // "Getting Started" page
35
- $hooks[] = add_dashboard_page(
36
- __( 'Getting started with Easing Slider', 'easingslider' ),
37
- __( 'Getting started with Easing Slider', 'easingslider' ),
38
- 'manage_options',
39
- 'easingslider-getting-started',
40
- array( $this, 'display_view' )
41
- );
42
-
43
- // "Credits" page
44
- $hooks[] = add_dashboard_page(
45
- __( 'The people that build Easing Slider', 'easingslider' ),
46
- __( 'The people that build Easing Slider', 'easingslider' ),
47
- 'manage_options',
48
- 'easingslider-credits',
49
- array( $this, 'display_view' )
50
- );
51
-
52
- // Page-specific hooks
53
- foreach ( $hooks as $hook ) {
54
- add_action( "admin_print_styles-{$hook}", array( $this, 'enqueue_styles' ) );
55
- }
56
-
57
- }
58
-
59
- /**
60
- * Registers all of our extensions page assets
61
- *
62
- * @return void
63
- */
64
- public function register_assets() {
65
-
66
- // Get our directory
67
- $css_dir = plugin_dir_url( Easing_Slider::$file ) . 'css';
68
-
69
- // Get file suffix
70
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
71
-
72
- // Register our stylesheet
73
- wp_register_style( 'easingslider-welcome-pages', "{$css_dir}/welcome-pages{$suffix}.css", false, Easing_Slider::$version );
74
-
75
- }
76
-
77
- /**
78
- * Enqueues all of our extensions page styles
79
- *
80
- * @return void
81
- */
82
- public function enqueue_styles() {
83
-
84
- // Enqueue our stylesheet
85
- wp_enqueue_style( 'easingslider-welcome-pages' );
86
-
87
- }
88
-
89
- /**
90
- * Hides the individual Dashboard pages
91
- *
92
- * @return void
93
- */
94
- public function hide_individual_pages() {
95
-
96
- // Remove the subpages
97
- remove_submenu_page( 'index.php', 'easingslider-about' );
98
- remove_submenu_page( 'index.php', 'easingslider-getting-started' );
99
- remove_submenu_page( 'index.php', 'easingslider-credits' );
100
-
101
- }
102
-
103
- /**
104
- * Gets the tabs for our "Welcome" page
105
- *
106
- * @return array
107
- */
108
- protected function get_tabs() {
109
-
110
- return apply_filters( 'easingslider_welcome_tabs', array(
111
- 'about' => array( 'title' => __( 'What\'s New', 'easingslider' ), 'slug' => 'about' ),
112
- 'getting-started' => array( 'title' => __( 'Getting Started', 'easingslider' ), 'slug' => 'getting-started' ),
113
- 'credits' => array( 'title' => __( 'Credits', 'easingslider' ), 'slug' => 'credits' )
114
- ) );
115
-
116
- }
117
-
118
- /**
119
- * Sets our redirect transient, used to tell us to redirect to the "Welcome" page(s)
120
- *
121
- * @return void
122
- */
123
- public function set_redirect_transient() {
124
-
125
- // Bail if activating from network, or bulk
126
- if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {
127
- return;
128
- }
129
-
130
- set_transient( '_easingslider_welcome_redirect', true, 30 );
131
-
132
- }
133
-
134
- /**
135
- * Redirects the user to the welcome page if welcome transient exits
136
- *
137
- * @return void
138
- */
139
- public function redirect_to_welcome() {
140
-
141
- // Bail if we have no transient
142
- if ( ! get_transient( '_easingslider_welcome_redirect' ) ) {
143
- return;
144
- }
145
-
146
- // Delete the redirect transient
147
- delete_transient( '_easingslider_welcome_redirect' );
148
-
149
- // Bail if activating from network, or bulk.
150
- if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {
151
- return;
152
- }
153
-
154
- // Get the previous plugin version from database
155
- $version = get_option( 'easingslider_version' );
156
-
157
- // Trigger hooks
158
- do_action( 'easingslider_pre_redirect_to_welcome', $version );
159
-
160
- // Redirect the user appropriately
161
- if ( version_compare( $version, Easing_Slider::$version, '=' ) ) {
162
-
163
- // This is a first time install. Redirect to "Getting Started".
164
- wp_safe_redirect( admin_url( 'index.php?page=easingslider-getting-started' ) );
165
- exit;
166
-
167
- }
168
- else {
169
-
170
- // The plugin has just been updated. Redirect to "About".
171
- wp_safe_redirect( admin_url( 'index.php?page=easingslider-about' ) );
172
- exit;
173
-
174
- }
175
-
176
- }
177
-
178
- /**
179
- * Displays the view
180
- *
181
- * @return void
182
- */
183
- public function display_view() {
184
-
185
- // Get the current page
186
- $page = sanitize_key( $_GET['page'] );
187
-
188
- // Get the settings tabs
189
- $tabs = $this->get_tabs();
190
-
191
- // Get the current tab
192
- $current_tab = str_replace( 'easingslider-', '', $page );
193
-
194
- // Get the plugin version
195
- $version = Easing_Slider::$version;
196
-
197
- // Get the images directory
198
- $image_dir = plugins_url( plugin_basename( dirname( __DIR__ ) ) ) . '/images';
199
-
200
- // Display the view
201
- require plugin_dir_path( dirname( __FILE__ ) ) . 'partials/welcome.php';
202
-
203
- }
204
-
205
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-es-widget.php DELETED
@@ -1,121 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Adds a 'Sliders' widget to the WordPress widgets interface
12
- *
13
- * @uses ES_Slider
14
- * @author Matthew Ruddy
15
- */
16
- class ES_Widget extends WP_Widget {
17
-
18
- /**
19
- * Constructor
20
- *
21
- * @return void
22
- */
23
- public function __construct() {
24
-
25
- // Call parent constructor
26
- parent::__construct(
27
- 'easingslider_widget',
28
- __( 'Slider', 'easingslider' ),
29
- array( 'description' => __( 'Display a slider using a widget', 'easingslider' ) )
30
- );
31
-
32
- }
33
-
34
- /**
35
- * Registers our widget
36
- *
37
- * @return void
38
- */
39
- public function register() {
40
-
41
- // Register this widget
42
- register_widget( __CLASS__ );
43
-
44
- }
45
-
46
- /**
47
- * Widget logic
48
- *
49
- * @param array $args The widget arguments
50
- * @param array $instance The widget instance
51
- * @return void
52
- */
53
- public function widget( $args, $instance ) {
54
-
55
- // Extract arguments
56
- extract( $args );
57
-
58
- // Before widget
59
- echo $before_widget;
60
-
61
- // Display title
62
- if ( ! empty( $instance['title'] ) ) {
63
- echo $before_title . apply_filters( 'widgets_title', $instance['title'] ) . $after_title;
64
- }
65
-
66
- // Display the slider
67
- if ( ! empty( $instance['id'] ) ) {
68
- echo do_shortcode( "[easingslider id=\"{$instance['id']}\"]" );
69
- }
70
-
71
- // After widget
72
- echo $after_widget;
73
-
74
- }
75
-
76
- /**
77
- * Returns updated settings array. Also does some sanatization.
78
- *
79
- * @param array $new_instance The new widget settings
80
- * @param array $old_instance The old widget settings
81
- * @return array
82
- */
83
- public function update( $new_instance, $old_instance ) {
84
-
85
- return array(
86
- 'id' => intval( $new_instance['id'] ),
87
- 'title' => strip_tags( $new_instance['title'] )
88
- );
89
-
90
- }
91
-
92
- /**
93
- * Widget settings form
94
- *
95
- * @param array $instance The widget instance
96
- */
97
- public function form( $instance ) {
98
-
99
- // Get all of the sliders
100
- $sliders = ES_Slider::all();
101
-
102
- // Print the settings
103
- ?>
104
- <p>
105
- <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'easingslider' ); ?></label>
106
- <input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" class="widefat" value="<?php if ( isset( $instance['title'] ) ) echo esc_attr( $instance['title'] ); ?>">
107
- </p>
108
- <p>
109
- <label for="<?php echo $this->get_field_id( 'id' ); ?>"><?php _e( 'Select Slider:', 'easingslider' ); ?></label>
110
- <select id="<?php echo $this->get_field_id( 'id' ); ?>" name="<?php echo $this->get_field_name( 'id' ); ?>" class="widefat">
111
- <option value="-1"><?php _e( '&#8212; Select &#8212;', 'easingslider' ); ?></option>
112
- <?php foreach ( $sliders as $slider ) : ?>
113
- <option value="<?php echo esc_attr( $slider->ID ); ?>" <?php if ( isset( $instance['id'] ) ) selected( $instance['id'], $slider->ID ); ?>><?php echo esc_html( $slider->post_title ) . sprintf( __( ' (ID #%s)', 'easingslider' ), $slider->ID ); ?></option>
114
- <?php endforeach; ?>
115
- </select>
116
- </p>
117
- <?php
118
-
119
- }
120
-
121
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/helpers.php DELETED
@@ -1,238 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Exit if accessed directly
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Alias for displaying a slider shortcode
12
- *
13
- * @uses ES_Shortcode
14
- *
15
- * @param int|array $args The slider arguments, or numerical ID.
16
- * @return void
17
- */
18
- if ( ! function_exists( 'easingslider' ) ) {
19
- function easingslider( $args = array() ) {
20
-
21
- // Continue if we have our shortcode class
22
- if ( class_exists( 'ES_Shortcode' ) ) {
23
-
24
- // Handle if we've passed just an ID
25
- if ( is_int( $args ) ) {
26
- $args = array( 'id' => $args );
27
- }
28
-
29
- // Create a new shortcode instance
30
- $shortcode = new ES_Shortcode();
31
-
32
- // Do the shortcode
33
- echo $shortcode->render( $args );
34
-
35
- }
36
-
37
- }
38
- }
39
-
40
- /**
41
- * Registers an extension, settings up it's licensing and updater.
42
- *
43
- * @uses ES_Update_Manager
44
- *
45
- * @param string $name The plugin name
46
- * @param string $file The plugin file
47
- * @param int $version The plugin version
48
- * @return ES_Update_Manager
49
- */
50
- if ( ! function_exists( 'easingslider_register_extension' ) ) {
51
- function easingslider_register_extension( $name, $file, $version ) {
52
-
53
- // Setup updates and licensing
54
- if ( class_exists( 'ES_Update_Manager' ) ) {
55
-
56
- // Hide advert
57
- add_filter( 'easingslider_show_advert', '__return_false' );
58
-
59
- // Initiate update manager
60
- $update_manager = new ES_Update_Manager( $name, $file, $version );
61
-
62
- return $update_manager;
63
- }
64
-
65
-
66
-
67
- }
68
- }
69
-
70
- /**
71
- * Helpful function for requiring a "partial" template file, or alternatively loading an action.
72
- * Often used for allowing extensions to hook into core plugin panels/views.
73
- *
74
- * @param string $name The file/action name
75
- * @param mixed $settings The data to pass to the file/action
76
- * @return void
77
- */
78
- if ( ! function_exists( 'easingslider_partial_or_action' ) ) {
79
- function easingslider_partial_or_action( $name, $settings = false ) {
80
-
81
- // Get the filepath
82
- $file_path = plugin_dir_path( dirname( __FILE__ ) ) . "partials/{$name}.php";
83
-
84
- // Load the file, or trigger an action if no file is found.
85
- if ( file_exists( $file_path ) ) {
86
- require $file_path;
87
- }
88
- else {
89
- do_action( "easingslider_{$name}", $settings );
90
- }
91
-
92
- }
93
- }
94
-
95
- /**
96
- * Queues an admin message to be displayed
97
- *
98
- * @param string $text The message text
99
- * @param string $type The message type (success, error, etc).
100
- * @return void
101
- */
102
- if ( ! function_exists( 'easingslider_admin_notice' ) ) {
103
- function easingslider_show_notice( $text, $type = 'updated' ) {
104
-
105
- // Add slashes to text
106
- $text = addslashes( $text );
107
-
108
- // Queue the message
109
- $message = "<div class='message $type'><p>$text</p></div>";
110
- add_action( 'admin_notices', create_function( '', 'echo "'. $message .'";' ) );
111
-
112
- }
113
- }
114
-
115
- /**
116
- * Adds a slider to the rendered slider global array.
117
- *
118
- * @param ES_Slider $slider The slider object
119
- * @return void
120
- */
121
- if ( ! function_exists( 'easingslider_store_rendered' ) ) {
122
- function easingslider_store_rendered( $slider ) {
123
-
124
- global $_rendered_sliders;
125
-
126
- // Add slider to the global
127
- $_rendered_sliders[] = $slider;
128
-
129
- }
130
- add_action( 'easingslider_render_slider', 'easingslider_store_rendered' );
131
- }
132
-
133
- /**
134
- * Gets the global array or rendered sliders.
135
- *
136
- * @return false|array
137
- */
138
- if ( ! function_exists( 'easingslider_get_rendered' ) ) {
139
- function easingslider_get_rendered() {
140
-
141
- global $_rendered_sliders;
142
-
143
- // If we have rendered sliders, return them. False if otherwise.
144
- if ( ! empty( $_rendered_sliders ) ) {
145
- return $_rendered_sliders;
146
- }
147
-
148
- return false;
149
-
150
- }
151
- }
152
-
153
- /**
154
- * Validates the data in an array for database insertion
155
- *
156
- * @param mixed $data The data to validate
157
- * @return mixed
158
- */
159
- if ( ! function_exists( 'easingslider_validate_data' ) ) {
160
- function easingslider_validate_data( $data ) {
161
-
162
- // Stripslashes
163
- $data = stripslashes_deep( $data );
164
-
165
- // Handle the various data types
166
- if ( is_object( $data ) OR is_array( $data ) ) {
167
- foreach ( $data as $key => &$value ) {
168
- $value = easingslider_validate_data( $value );
169
- }
170
- }
171
- else if ( is_string( $data ) && ( ! is_object( json_decode( $data ) ) OR ! is_array( json_decode( $data ) ) ) ) {
172
-
173
- // Bail if just an empty string
174
- if ( $data == '' ) {
175
- return $data;
176
- }
177
-
178
- // Ensure integers are integers, and booleans are booleans
179
- if ( ! is_null( ( $int = filter_var( $data, FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE ) ) ) ) {
180
- $data = $int;
181
- }
182
- else if ( ! is_null( ( $bool = filter_var( $data, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) ) ) ) {
183
- $data = $bool;
184
- }
185
-
186
- }
187
-
188
- return $data;
189
-
190
- }
191
- }
192
-
193
- /**
194
- * Generates a HTML attributes string, filtering for good measure.
195
- *
196
- * @param string $slug The slug, used in the filter
197
- * @param array $atts The html attributes array
198
- * @return string
199
- */
200
- if ( ! function_exists( 'easingslider_html_attributes_string' ) ) {
201
- function easingslider_html_attributes_string( $slug, $atts = array(), $output = '' ) {
202
-
203
- // Filter the attributes
204
- $atts = apply_filters( "easingslider_{$slug}_html_attributes", $atts );
205
-
206
- // Generate the string
207
- foreach ( $atts as $key => $value ) {
208
- if ( ! $value ) {
209
- $output .= "{$key}=\"{$value}\" ";
210
- }
211
- }
212
-
213
- return $output;
214
-
215
- }
216
- }
217
-
218
- /**
219
- * Displays admin footer text, thanking the user for using Easing Slider :)
220
- *
221
- * @param string $footer_text The current footer text
222
- * @return string
223
- */
224
- if ( ! function_exists( 'easingslider_admin_footer_text' ) ) {
225
- function easingslider_admin_footer_text( $footer_text ) {
226
-
227
- global $current_screen;
228
-
229
- // Only display custom text on Easing Slider pages
230
- if ( isset( $current_screen->id ) && false !== strpos( $current_screen->id, 'easingslider' ) ) {
231
- return sprintf( __( 'Please rate <strong>Easing Slider</strong> <a href="%1$s" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href="%1$s" target="_blank">WordPress.org</a> to help us keep this plugin free. Thank you from the Easing Slider team!', 'easingslider' ), __( 'http://wordpress.org/support/view/plugin-reviews/easing-slider?filter=5', 'easingslider' ) );
232
- } else {
233
- return $footer_text;
234
- }
235
-
236
- }
237
- add_filter( 'admin_footer_text', 'easingslider_admin_footer_text' );
238
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/customizer.js DELETED
@@ -1,197 +0,0 @@
1
- /**
2
- * Globalize
3
- */
4
- window.EasingSlider = window.EasingSlider || { Customizer: { models: {}, views: {} } };
5
-
6
- /**
7
- * Where the magic happens!
8
- */
9
- (function($) {
10
-
11
- var Customizer = window.EasingSlider.Customizer;
12
-
13
- /**
14
- * Customizer View
15
- */
16
- Customizer.views.Customizer = Backbone.View.extend({
17
-
18
- /**
19
- * Our view element
20
- */
21
- el: '.customize-container',
22
-
23
- /**
24
- * Events
25
- */
26
- events: {
27
- 'change #change-slider': '_changeSlider',
28
- 'change [data-selector]': '_reflectChanges',
29
- 'click .collapse-sidebar': '_toggleSidebar',
30
- 'click .accordion-section-title': '_toggleSection'
31
- },
32
-
33
- /**
34
- * Constructor
35
- */
36
- initialize: function() {
37
-
38
- var view = this;
39
-
40
- // Inititiate color pickers
41
- this.$('.color-picker-hex').each(function() {
42
- $(this).wpColorPicker({
43
- change: view._reflectChanges,
44
- defaultColor: $(this).attr('data-default')
45
- });
46
- });
47
-
48
- },
49
-
50
- /**
51
- * Changes the slider, reloading the page.
52
- */
53
- _changeSlider: function(event) {
54
-
55
- // Redirect the page
56
- window.location.href = 'http://'+ window.location.hostname + window.location.pathname + '?page=easingslider_manage_customizations&edit='+ event.target.value;
57
-
58
- },
59
-
60
- /**
61
- * Reflects changes made to inputs on the provided selector.
62
- * This provides a live preview of the changes as they are made.
63
- */
64
- _reflectChanges: function(event) {
65
-
66
- // Prefix and suffix the value as necessary
67
- switch ( event.target.dataset.property ) {
68
-
69
- case 'background-image':
70
- $(event.target.dataset.selector).css({
71
- 'background-image': 'url('+ event.target.value +')'
72
- });
73
- break;
74
-
75
- case 'border-width':
76
- $(event.target.dataset.selector).css({
77
- 'border-style': 'solid',
78
- 'border-width': event.target.value +'px'
79
- });
80
- break;
81
-
82
- case 'border-radius':
83
- $(event.target.dataset.selector).css({
84
- '-webkit-border-radius': event.target.value +'px',
85
- '-moz-border-radius': event.target.value +'px',
86
- 'border-radius': event.target.value +'px'
87
- });
88
- break;
89
-
90
- case 'display':
91
- if ( 'true' == event.target.value ) {
92
- $(event.target.dataset.selector).css('display', 'block');
93
- }
94
- else {
95
- $(event.target.dataset.selector).css('display', 'none');
96
- }
97
- break;
98
-
99
- case 'src':
100
- $(event.target.dataset.selector).attr('src', event.target.value);
101
- break;
102
-
103
- default:
104
- $(event.target.dataset.selector).css(event.target.dataset.property, event.target.value);
105
- break;
106
-
107
- }
108
-
109
- },
110
-
111
- /**
112
- * Toggles the sidebar
113
- */
114
- _toggleSidebar: function(event) {
115
-
116
- event.preventDefault();
117
-
118
- // Expand/collapse the sidebar
119
- if ( this.$('.wp-full-overlay').hasClass('expanded') ) {
120
- this.$('.wp-full-overlay').removeClass('expanded').addClass('collapsed');
121
- }
122
- else {
123
- this.$('.wp-full-overlay').removeClass('collapsed').addClass('expanded');
124
- }
125
-
126
- },
127
-
128
- /**
129
- * Toggles a section
130
- */
131
- _toggleSection: function(event) {
132
-
133
- event.preventDefault();
134
-
135
- // Loop through and toggle each section appropriately
136
- this.$('.accordion-section-title').each(function() {
137
-
138
- // Get the inside
139
- var $section = $(this).closest('.accordion-section'),
140
- $inside = $section.find('.accordion-section-content');
141
-
142
- // Determine if this is the clicked section, or another section.
143
- if ( this == event.currentTarget ) {
144
-
145
- // If the clicked section is already open, close it. Otherwise, open it.
146
- if ( $section.hasClass('open') ) {
147
-
148
- // "Slide Up" the section content then close it entirely
149
- $inside.slideUp({
150
- duration: 'fast',
151
- easing: 'linear',
152
- complete: function() {
153
- $section.removeClass('open');
154
- }
155
- });
156
-
157
- }
158
- else {
159
-
160
- // Open the section
161
- $section.addClass('open');
162
-
163
- // "Slide Down" the content
164
- $inside.css({ 'display': 'none' }).slideDown('fast');
165
-
166
- }
167
- }
168
- else {
169
-
170
- // "Slide Up" the section content then close it entirely
171
- $inside.slideUp({
172
- duration: 'fast',
173
- easing: 'linear',
174
- complete: function() {
175
- $section.removeClass('open');
176
- }
177
- });
178
-
179
- }
180
-
181
- });
182
-
183
- }
184
-
185
- });
186
-
187
- /**
188
- * Let's go!
189
- */
190
- $(document).ready(function() {
191
-
192
- // Initiate the view
193
- new Customizer.views.Customizer();
194
-
195
- });
196
-
197
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/customizer.min.js DELETED
@@ -1 +0,0 @@
1
- window.EasingSlider=window.EasingSlider||{Customizer:{models:{},views:{}}},function(e){var t=window.EasingSlider.Customizer;t.views.Customizer=Backbone.View.extend({el:".customize-container",events:{"change #change-slider":"_changeSlider","change [data-selector]":"_reflectChanges","click .collapse-sidebar":"_toggleSidebar","click .accordion-section-title":"_toggleSection"},initialize:function(){var t=this;this.$(".color-picker-hex").each(function(){e(this).wpColorPicker({change:t._reflectChanges,defaultColor:e(this).attr("data-default")})})},_changeSlider:function(e){window.location.href="http://"+window.location.hostname+window.location.pathname+"?page=easingslider_manage_customizations&edit="+e.target.value},_reflectChanges:function(t){switch(t.target.dataset.property){case"background-image":e(t.target.dataset.selector).css({"background-image":"url("+t.target.value+")"});break;case"border-width":e(t.target.dataset.selector).css({"border-style":"solid","border-width":t.target.value+"px"});break;case"border-radius":e(t.target.dataset.selector).css({"-webkit-border-radius":t.target.value+"px","-moz-border-radius":t.target.value+"px","border-radius":t.target.value+"px"});break;case"display":"true"==t.target.value?e(t.target.dataset.selector).css("display","block"):e(t.target.dataset.selector).css("display","none");break;case"src":e(t.target.dataset.selector).attr("src",t.target.value);break;default:e(t.target.dataset.selector).css(t.target.dataset.property,t.target.value)}},_toggleSidebar:function(e){e.preventDefault(),this.$(".wp-full-overlay").hasClass("expanded")?this.$(".wp-full-overlay").removeClass("expanded").addClass("collapsed"):this.$(".wp-full-overlay").removeClass("collapsed").addClass("expanded")},_toggleSection:function(t){t.preventDefault(),this.$(".accordion-section-title").each(function(){var a=e(this).closest(".accordion-section"),s=a.find(".accordion-section-content");this==t.currentTarget?a.hasClass("open")?s.slideUp({duration:"fast",easing:"linear",complete:function(){a.removeClass("open")}}):(a.addClass("open"),s.css({display:"none"}).slideDown("fast")):s.slideUp({duration:"fast",easing:"linear",complete:function(){a.removeClass("open")}})})}}),e(document).ready(function(){new t.views.Customizer})}(jQuery);
 
js/editor-pages.js DELETED
@@ -1,1274 +0,0 @@
1
- /**
2
- * Globalize
3
- */
4
- window.EasingSlider = window.EasingSlider || {
5
- Editor: {
6
- models: {},
7
- collections: {},
8
- controllers: {},
9
- frames: {},
10
- views: {},
11
- router: {},
12
- Router: {}
13
- }
14
- };
15
-
16
- /**
17
- * Where the magic happens!
18
- */
19
- (function($) {
20
-
21
- var Editor = window.EasingSlider.Editor;
22
-
23
- /**
24
- * Our slide types
25
- */
26
- Editor.models.Slide = {
27
-
28
- /**
29
- * Returns the appropriate "Slide" model
30
- */
31
- get: function(attributes) {
32
- return new Editor.models.Slide[attributes.type](attributes);
33
- }
34
-
35
- };
36
-
37
- /**
38
- * Image "Slide" model
39
- */
40
- Editor.models.Slide.image = Backbone.Model.extend({
41
-
42
- /**
43
- * Attachment
44
- */
45
- attachment: false,
46
-
47
- /**
48
- * Defaults
49
- */
50
- defaults: _.defaults({
51
- attachment_id: null,
52
- type: 'image',
53
- alt: '',
54
- aspectRatio: null,
55
- link: 'none',
56
- linkUrl: '',
57
- linkTargetBlank: false,
58
- title: '',
59
- url: null
60
- }, wp.media.model.PostImage.prototype.defaults)
61
-
62
- });
63
-
64
- /**
65
- * Our slides collection
66
- */
67
- Editor.collections.Slides = Backbone.Collection.extend({
68
-
69
- /**
70
- * The models for this collection are polymorphic,
71
- * so the model to add is determined by function.
72
- *
73
- * Don't be fooled, Editor.models.Slide.get is just a function (not a model).
74
- */
75
- model: Editor.models.Slide.get,
76
-
77
- /**
78
- * Constructor
79
- */
80
- initialize: function() {
81
-
82
- // Bind our collection events
83
- this.on('add', this._resetIDs, this);
84
- this.on('remove', this._resetIDs, this);
85
- this.on('reset', this._resetIDs, this);
86
-
87
- },
88
-
89
- /**
90
- * Comparator
91
- */
92
- comparator: function(model) {
93
-
94
- return model.get('id');
95
-
96
- },
97
-
98
- /**
99
- * Resets the ID attribute on each model
100
- */
101
- _resetIDs: function() {
102
-
103
- // Create a new collection. We need to do this to avoid issues with duplicate IDs.
104
- var collection = new Backbone.Collection();
105
-
106
- // Loop through each model and update the ID attribute. Then add it to our collection.
107
- _.each(this.models, function(model, index) {
108
- model.set({ id: index + 1 });
109
-
110
- collection.add(model);
111
- });
112
-
113
- // Reset this collection with the models from our temporary collection
114
- this.reset(collection.models, { silent: true });
115
-
116
- },
117
-
118
- /**
119
- * Repositions a model to the specified index in the collection
120
- */
121
- reposition: function(model, index) {
122
-
123
- // Remove the model
124
- this.remove(model, { silent: true });
125
-
126
- // Add the model at our desired index
127
- this.add(model, { at: index, silent: true });
128
-
129
- // Reset the IDs
130
- this._resetIDs();
131
-
132
- return this;
133
-
134
- },
135
-
136
- /**
137
- * Syncs the models in this collection
138
- */
139
- sync: function() {
140
-
141
- var collection = this,
142
- ids = [];
143
-
144
- // Loop through each model and get attachment IDs
145
- _.each(this.models, function(model) {
146
-
147
- // Check if the model has an attachment ID
148
- if ( model.has('attachment_id') ) {
149
- ids.push(model.get('attachment_id'));
150
- }
151
-
152
- }, this);
153
-
154
- // Query the WordPress Media Library
155
- var query = wp.media.query({
156
- post__in: ids,
157
- posts_per_page: -1
158
- });
159
-
160
- // Do the query
161
- query.more().done(function() {
162
- _.each(query.models, function(attachment) {
163
-
164
- // Get models with a matching ID
165
- var matches = collection.where({ attachment_id: attachment.get('id') });
166
-
167
- // Loop through each match
168
- _.each(matches, function(model) {
169
-
170
- // Set the attachment object
171
- model.attachment = attachment;
172
-
173
- });
174
-
175
- });
176
-
177
- // Trigger a sync action
178
- collection.trigger('sync:done');
179
- });
180
-
181
- return this;
182
-
183
- }
184
-
185
- });
186
-
187
- /**
188
- * Our "Add Slide" controllers for various slide types
189
- */
190
- Editor.controllers.AddSlide = {
191
-
192
- /**
193
- * Returns the appropriate "Add Slide" controller, based on the type of slide provided
194
- */
195
- get: function(options) {
196
- return new Editor.controllers.AddSlide[options.type](options);
197
- }
198
-
199
- };
200
-
201
- /**
202
- * "Add Slide" controller for images
203
- */
204
- Editor.controllers.AddSlide.image = wp.media.controller.Library.extend();
205
-
206
- /**
207
- * Our "Edit Slide" controllers for various slide types
208
- */
209
- Editor.controllers.EditSlide = {
210
-
211
- /**
212
- * Returns the appropriate "Edit Slide" controller, based on the type of slide provided
213
- */
214
- get: function(options) {
215
- return new Editor.controllers.EditSlide[options.type](options);
216
- }
217
-
218
- };
219
-
220
- /**
221
- * "Edit Slide" controller for images
222
- */
223
- Editor.controllers.EditSlide.image = wp.media.controller.ImageDetails.extend({
224
-
225
- /**
226
- * Defaults
227
- */
228
- defaults: _.defaults({
229
- id: 'edit-slide',
230
- title: _easingsliderEditorL10n.media_upload.title
231
- }, wp.media.controller.ImageDetails.prototype.defaults )
232
-
233
- });
234
-
235
- /**
236
- * "Add Slide" WordPress Media Frame
237
- */
238
- Editor.frames.AddSlide = wp.media.view.MediaFrame.Post.extend({
239
-
240
- /**
241
- * Constructor
242
- */
243
- initialize: function() {
244
-
245
- // Alter defaults
246
- _.defaults(this.options, {
247
- multiple: true
248
- });
249
-
250
- // Call parent constructor
251
- wp.media.view.MediaFrame.Post.prototype.initialize.apply(this, arguments);
252
-
253
- // Bind Handlers
254
- this.on('content:render:browse', this.removeSidebar, this);
255
- this.on('toolbar:create:insert-slide', this.createToolbar, this);
256
- this.on('toolbar:render:insert-slide', this.insertToolbar, this);
257
-
258
- },
259
-
260
- /**
261
- * Render callback for the content region in the 'browse' mode.
262
- */
263
- browseContent: function(contentRegion) {
264
-
265
- // Get the state
266
- var state = this.state();
267
-
268
- // Show the toolbar
269
- this.$el.removeClass('hide-toolbar');
270
-
271
- // Browse our library of attachments
272
- contentRegion.view = new Editor.views.AddSlide.image({
273
- controller: this,
274
- collection: state.get('library'),
275
- selection: state.get('selection'),
276
- model: state,
277
- sortable: state.get('sortable'),
278
- search: state.get('searchable'),
279
- filters: state.get('filterable'),
280
- date: state.get('date'),
281
- display: state.has('display') ? state.get('display') : state.get('displaySettings'),
282
- dragInfo: state.get('dragInfo'),
283
- idealColumnWidth: state.get('idealColumnWidth'),
284
- suggestedWidth: state.get('suggestedWidth'),
285
- suggestedHeight: state.get('suggestedHeight'),
286
- AttachmentView: state.get('AttachmentView')
287
- });
288
-
289
- },
290
-
291
- /**
292
- * Creates our states
293
- */
294
- createStates: function() {
295
-
296
- // Add the default states
297
- this.states.add([
298
- new Editor.controllers.AddSlide.image({
299
- id: 'insert',
300
- type: 'image',
301
- title: _easingsliderEditorL10n.media_upload.image_from_media,
302
- priority: 20,
303
- toolbar: 'insert-slide',
304
- filterable: false,
305
- library: wp.media.query({ type: 'image' }),
306
- multiple: true,
307
- editable: true,
308
- allowLocalEdits: true,
309
- displaySettings: false,
310
- displayUserSettings: true
311
- })
312
- ]);
313
-
314
- },
315
-
316
- /**
317
- * Removes the sidebar from the frame
318
- */
319
- removeSidebar: function(view) {
320
-
321
- // Remove the sidebar
322
- view.sidebar.remove('details');
323
-
324
- // Hide sidebar altogether
325
- view.$el.addClass('hide-sidebar');
326
-
327
- },
328
-
329
- /**
330
- * Adds our "Insert into Slider" toolbar
331
- */
332
- insertToolbar: function(view) {
333
-
334
- var controller = this;
335
-
336
- // Add the toolbar to our provided view
337
- view.set('insert-slide', {
338
- style: 'primary',
339
- priority: 80,
340
- text: _easingsliderEditorL10n.media_upload.insert_into_slider,
341
- requires: { selection: false },
342
- click: function() {
343
-
344
- // Close then trigger "insert", providing the selection
345
- controller.close().trigger('insert', controller.getSelection()).reset();
346
-
347
- }
348
- });
349
-
350
- },
351
-
352
- /**
353
- * Prepares & returns our selection for handoff to our view(s)
354
- */
355
- getSelection: function(selection) {
356
-
357
- var collection = new wp.media.model.Selection(null, { multiple: true });
358
-
359
- // Get the type & selection
360
- var type = this.state().get('type'),
361
- selection = this.state().get('selection');
362
-
363
- // Loop through each selection
364
- _.each(selection.models, function(model) {
365
-
366
- // Create a new slide & set its type
367
- var slide = new Editor.models.Slide.get({
368
- type: type
369
- });
370
-
371
- // Handle attachments (attachments will have an ID attribute)
372
- if ( model.get('id') ) {
373
- slide.attachment = model;
374
- slide.set({ attachment_id: model.get('id') }, { silent: true });
375
- }
376
- else {
377
- slide.set(model, { silent: true });
378
- }
379
-
380
- // Add to the collection
381
- collection.add(slide);
382
-
383
- }, this);
384
-
385
- return collection;
386
-
387
- }
388
-
389
- });
390
-
391
- /**
392
- * Our "Edit Slide" frames for various slide types
393
- */
394
- Editor.frames.EditSlide = {
395
-
396
- /**
397
- * Returns the appropriate "Edit Slide" frame, based on the type of slide provided
398
- */
399
- get: function(options) {
400
- return new Editor.frames.EditSlide[options.model.get('type')](options);
401
- }
402
-
403
- };
404
-
405
- /**
406
- * Frame for editing an "Image" slide
407
- */
408
- Editor.frames.EditSlide.image = wp.media.view.MediaFrame.ImageDetails.extend({
409
-
410
- /**
411
- * Constructor
412
- */
413
- initialize: function() {
414
-
415
- // Set the image
416
- this.image = new wp.media.model.PostImage(this.model.attributes);
417
-
418
- // Set our options
419
- this.options.state = 'edit-slide';
420
- this.options.selection = new wp.media.model.Selection(this.image.attachment, { multiple: false });
421
-
422
- // Call parent constructor
423
- wp.media.view.MediaFrame.Select.prototype.initialize.apply(this, arguments);
424
-
425
- // Bind events
426
- this.on('content:render:browse', this.removeSidebar, this);
427
- this.state('edit-slide').on('update', this.updateSettings, this);
428
- this.state('replace-image').on('replace', this.replaceImage, this);
429
-
430
- },
431
-
432
- /**
433
- * Creates our states
434
- */
435
- createStates: function() {
436
-
437
- // Add our "Edit Slide" state
438
- this.states.add([
439
- new Editor.controllers.EditSlide.get({
440
- type: 'image',
441
- image: this.image,
442
- editable: false
443
- })
444
- ]);
445
-
446
- // Call parent states
447
- wp.media.view.MediaFrame.ImageDetails.prototype.createStates.apply(this, arguments);
448
-
449
- },
450
-
451
- /**
452
- * Replaces the "Image Details" section with our "Edit Slide" instead.
453
- *
454
- * Bit of a hack, but it works.
455
- */
456
- imageDetailsContent: function(options) {
457
-
458
- // Initiate the view
459
- options.view = new Editor.views.EditSlide.get({
460
- type: 'image',
461
- controller: this,
462
- model: this.state().image,
463
- attachment: this.state().image.attachment
464
- });
465
-
466
- },
467
-
468
- /**
469
- * Removes the sidebar from the frame
470
- */
471
- removeSidebar: function(view) {
472
-
473
- // Remove the sidebar
474
- view.sidebar.remove('details');
475
-
476
- // Hide sidebar altogether
477
- view.$el.addClass('hide-sidebar');
478
-
479
- },
480
-
481
- /**
482
- * Applies a setting change to the model
483
- */
484
- updateSettings: function() {
485
-
486
- var data = {};
487
-
488
- // Gather the settings
489
- this.$('*[data-setting]').each(function() {
490
-
491
- // Handle setting
492
- if ( 'checkbox' == this.type ) {
493
- data[this.dataset.setting] = ( this.checked ) ? this.value : false;
494
- }
495
- else {
496
- data[this.dataset.setting] = this.value;
497
- }
498
-
499
- });
500
-
501
- // Set the model data
502
- this.model.set(data);
503
-
504
- },
505
-
506
- /**
507
- * Replaces the image
508
- *
509
- * This functionality is only available to attachment,
510
- * so we can safely assume this is one.
511
- */
512
- replaceImage: function() {
513
-
514
- // Replace the attachment
515
- this.model.set({ attachment_id: this.image.attachment.id });
516
- this.model.attachment.set(this.image.attachment.attributes);
517
-
518
- }
519
-
520
- });
521
-
522
- /**
523
- * Admin view
524
- */
525
- Editor.views.Admin = Backbone.View.extend({
526
-
527
- /**
528
- * Our view element
529
- */
530
- el: '.wrap',
531
-
532
- /**
533
- * Events
534
- */
535
- events: {
536
- 'click #add-slides': '_addSlide',
537
- 'click #select-all': '_selectAll',
538
- 'click #delete-slides': '_clickBulkDelete',
539
- 'click #save': '_clickSave',
540
- 'click .toolbar .edit': '_clickEdit',
541
- 'click .toolbar .remove': '_clickDelete',
542
- 'click .show-advanced-options': '_clickAdvancedOptions',
543
- 'click .thumbnail': '_clickThumb',
544
- 'click .select-mode-toggle-button': '_toggleMode',
545
- 'click .sidebar-name': '_toggleWidget'
546
- },
547
-
548
- /**
549
- * Constructor
550
- */
551
- initialize: function() {
552
-
553
- // Initiate our subviews
554
- this.subviews = {
555
- AddSlide: new Editor.frames.AddSlide(),
556
- AdminSlides: new Editor.views.AdminSlides({
557
- collection: this.collection
558
- })
559
- };
560
-
561
- // Bind our events
562
- this.collection.on('sync:done', this.render, this);
563
- this.collection.on('sync:done', this._enableSave, this);
564
- this.subviews.AddSlide.on('insert', this._handleInsert, this);
565
-
566
- // Change number of columns on window resize
567
- $(window).on('resize', this._setColumns.bind(this));
568
-
569
- // Disable select mode
570
- this._selectMode = false;
571
-
572
- // Set number of columns
573
- this._setColumns();
574
-
575
- // Show the spinner
576
- this._showSpinner();
577
-
578
- },
579
-
580
- /**
581
- * Shows the spinner
582
- */
583
- _showSpinner: function() {
584
-
585
- this.$('#slides-browser').append('<div class="spinner"></div>');
586
-
587
- },
588
-
589
- /**
590
- * Hides the spinner
591
- */
592
- _hideSpinner: function() {
593
-
594
- this.$('#slides-browser .spinner').remove();
595
-
596
- },
597
-
598
- /**
599
- * Enables the save button
600
- */
601
- _enableSave: function() {
602
-
603
- this.$('#save').prop('disabled', false);
604
-
605
- },
606
-
607
- /**
608
- * Handles save button click
609
- */
610
- _clickSave: function() {
611
-
612
- this.$('#publishing-action .spinner').css({ 'display': 'block' });
613
-
614
- },
615
-
616
- /**
617
- * Sets the appropriate number of columns
618
- */
619
- _setColumns: function() {
620
-
621
- var content = this.$('.media-frame-content'),
622
- previous_columns = content.attr('data-columns'),
623
- width = content.width();
624
-
625
- // Continue if we have width
626
- if ( width ) {
627
-
628
- // Calculate the maximum number of columns we can fit
629
- var columns = Math.min(Math.round(width / 145), 12) || 1;
630
-
631
- // Change the number of columns if it's not the same as previously
632
- if ( ! previous_columns || previous_columns !== columns ) {
633
- content.attr('data-columns', columns);
634
- }
635
-
636
- }
637
-
638
- },
639
-
640
- /**
641
- * Handles slide(s) insert from the "Add Slide" frame view
642
- */
643
- _handleInsert: function(selection) {
644
-
645
- // Add to the collection
646
- this.collection.add(selection.models);
647
-
648
- },
649
-
650
- /**
651
- * Handles a thumbnail click event
652
- */
653
- _clickThumb: function(event) {
654
-
655
- event.preventDefault();
656
-
657
- // Handle click based on mode
658
- if ( ! this._selectMode ) {
659
- this._editSlide(event);
660
- }
661
- else {
662
- this._toggleSelect(event);
663
- }
664
-
665
- },
666
-
667
- /**
668
- * Handles an "edit" button click event
669
- */
670
- _clickEdit: function(event) {
671
-
672
- event.preventDefault();
673
-
674
- this._editSlide(event);
675
-
676
- },
677
-
678
- /**
679
- * Handles a "delete" button click event
680
- */
681
- _clickDelete: function(event) {
682
-
683
- event.preventDefault();
684
-
685
- if ( confirm( _easingsliderEditorL10n.warn ) ) {
686
-
687
- // Get the model ID
688
- var id = $(event.currentTarget).parents('.attachment').attr('data-id');
689
-
690
- // Delete the model from the collection
691
- this.collection.remove(id);
692
-
693
- }
694
-
695
- },
696
-
697
- /**
698
- * Handles a bulk delete button click
699
- */
700
- _clickBulkDelete: function(event) {
701
-
702
- event.preventDefault();
703
-
704
- if ( confirm( _easingsliderEditorL10n.warn ) ) {
705
-
706
- // Delete the slides
707
- this._deleteSlides(event);
708
-
709
- // Toggle mode
710
- this._toggleMode(event);
711
-
712
- }
713
-
714
- },
715
-
716
- /**
717
- * Handles "advanced options" link click
718
- */
719
- _clickAdvancedOptions: function(event) {
720
-
721
- event.preventDefault();
722
-
723
- // Get the advanced options
724
- var $options = $(event.currentTarget).parent().find('.advanced-options');
725
-
726
- // Find the closest advanced options and show it
727
- $options.toggleClass('hidden');
728
-
729
- },
730
-
731
- /**
732
- * Toggles between "Bulk Select" mode
733
- */
734
- _toggleMode: function(event) {
735
-
736
- event.preventDefault();
737
-
738
- // Toggle mode
739
- if ( ! this._selectMode ) {
740
- this._selectMode = true;
741
- }
742
- else {
743
- this._selectMode = false;
744
- }
745
-
746
- // Toggle select mode class
747
- this.$('.attachment').removeClass('selected details');
748
- this.$('.media-frame').toggleClass('mode-select');
749
- this.$('.media-toolbar div *').toggleClass('hidden');
750
-
751
- },
752
-
753
- /**
754
- * Toggles selection of a slide on click
755
- */
756
- _toggleSelect: function(event) {
757
-
758
- event.preventDefault()
759
-
760
- // Highlight the thumbnail
761
- $(event.currentTarget).parents('.attachment').toggleClass('selected details');
762
-
763
- },
764
-
765
- /**
766
- * Toggles a sidebar settings widget metabox
767
- */
768
- _toggleWidget: function(event) {
769
-
770
- event.preventDefault();
771
-
772
- var $widget = $(event.currentTarget).parent(),
773
- $content = $widget.find('.sidebar-content');
774
-
775
- // Bail if this is a fixed widget
776
- if ( $widget.hasClass('fixed') ) {
777
- return;
778
- }
779
-
780
- // Close any open sidebar metaboxes
781
- this.$('.widgets-holder-wrap').each(function() {
782
- var $metabox = $(this);
783
-
784
- if ( ! $metabox.hasClass('fixed') ) {
785
- $metabox.find('.sidebar-content').slideUp(200, function() {
786
- $metabox.addClass('closed');
787
- });
788
- }
789
- });
790
-
791
- // Bail if the clicked widget is already open
792
- if ( ! $widget.hasClass('closed') ) {
793
- return;
794
- }
795
-
796
- // Open the sidebar metabox
797
- $content.slideDown(200, function() {
798
- $widget.removeClass('closed');
799
- });
800
-
801
- },
802
-
803
- /**
804
- * Selects all of the slides
805
- */
806
- _selectAll: function(event) {
807
-
808
- event.preventDefault();
809
-
810
- // Highlight all the thumbnails
811
- this.$('.attachment').addClass('selected details');
812
-
813
- },
814
-
815
- /**
816
- * Deletes the currently selected slides
817
- */
818
- _deleteSlides: function(event) {
819
-
820
- event.preventDefault();
821
-
822
- // Establish variables
823
- var collection = this.collection,
824
- models = [];
825
-
826
- // Loop through each slide and remove selected
827
- this.$('.attachment').each(function(index) {
828
-
829
- // Check if this slide has been selected & add it to be removed if so.
830
- if ( $(this).hasClass('selected') ) {
831
- models.push(collection.at(index));
832
- }
833
-
834
- });
835
-
836
- // Remove the models from the collection
837
- this.collection.remove(models);
838
-
839
- },
840
-
841
- /**
842
- * Opens the "Add Slide" frame view on click
843
- */
844
- _addSlide: function(event) {
845
-
846
- event.preventDefault();
847
-
848
- // Open the frame
849
- this.addSlide();
850
-
851
- },
852
-
853
- /**
854
- * Opens the "Add Slide" frame
855
- */
856
- addSlide: function() {
857
-
858
- // Open the "Add Slide" frame
859
- this.subviews.AddSlide.open();
860
-
861
- return this;
862
-
863
- },
864
-
865
- /**
866
- * Opens the "Edit Slide" frame on click
867
- */
868
- _editSlide: function(event) {
869
-
870
- event.preventDefault();
871
-
872
- // Get the slide ID
873
- var id = $(event.currentTarget).parents('.attachment').attr('data-id');
874
-
875
- // Open the frame
876
- this.editSlide(id);
877
-
878
- },
879
-
880
- /**
881
- * Opens the "Edit Slide" frame
882
- */
883
- editSlide: function(id) {
884
-
885
- // Create the frame
886
- this.subviews.EditSlide = new Editor.frames.EditSlide.get({
887
- model: this.collection.get(id)
888
- });
889
-
890
- // Open the frame
891
- this.subviews.EditSlide.open();
892
-
893
- return this;
894
-
895
- },
896
-
897
- /**
898
- * Renders the view
899
- */
900
- render: function() {
901
-
902
- // Hide the spinner
903
- this._hideSpinner();
904
-
905
- // Render the subview
906
- var slides = this.subviews.AdminSlides.render().el;
907
-
908
- // Add the slides to the view
909
- this.$('#slides-browser').append(slides);
910
-
911
- return this;
912
-
913
- }
914
-
915
- });
916
-
917
- /**
918
- * Admin "Slides" view
919
- */
920
- Editor.views.AdminSlides = Backbone.View.extend({
921
-
922
- /**
923
- * Tagname
924
- */
925
- tagName: 'ul',
926
-
927
- /**
928
- * Attributes
929
- */
930
- attributes: {
931
- 'class': 'attachments ui-sortable',
932
- 'tabindex': '-1'
933
- },
934
-
935
- /**
936
- * Constructor
937
- */
938
- initialize: function() {
939
-
940
- // Subviews
941
- this.subviews = [];
942
-
943
- // Bind our collection events
944
- this.collection.on('add', this.add, this);
945
- this.collection.on('remove', this.render, this);
946
- this.collection.on('reset', this.render, this);
947
-
948
- // Enable sorting
949
- this.$el.sortable({
950
- items: '.attachment',
951
- containment: 'parent',
952
- tolerance: 'pointer',
953
- stop: this._sort.bind(this)
954
- });
955
-
956
- },
957
-
958
- /**
959
- * Sorts the view
960
- */
961
- _sort: function(event, ui) {
962
-
963
- // Get the model
964
- var model = this.collection.get(ui.item.context.dataset.id);
965
-
966
- // Reposition the model in the collection
967
- this.collection.reposition(model, ui.item.index());
968
-
969
- },
970
-
971
- /**
972
- * Adds a subview
973
- */
974
- add: function(model) {
975
-
976
- // Render and add the slide to the view
977
- var view = new Editor.views.AdminSlide({
978
- model: model
979
- });
980
-
981
- // Add the subview
982
- this.subviews.push(view);
983
-
984
- // Render and append subview to this view
985
- this.$el.append(view.render().$el);
986
-
987
- return this;
988
-
989
- },
990
-
991
- /**
992
- * Renders the view
993
- */
994
- render: function() {
995
-
996
- this.subviews = [];
997
-
998
- // Empty the view
999
- this.$el.empty();
1000
-
1001
- // Render each subview
1002
- _.each(this.collection.models, function(model) {
1003
- this.add(model);
1004
- }, this);
1005
-
1006
- return this;
1007
-
1008
- }
1009
-
1010
- });
1011
-
1012
- /**
1013
- * Admin "Slide" view
1014
- */
1015
- Editor.views.AdminSlide = Backbone.View.extend({
1016
-
1017
- /**
1018
- * Tagname
1019
- */
1020
- tagName: 'li',
1021
-
1022
- /**
1023
- * Attributes
1024
- */
1025
- attributes: function() {
1026
- return {
1027
- 'role': 'checkbox',
1028
- 'class': 'attachment save-ready',
1029
- 'tabindex': '0',
1030
- 'data-id': this.model.id
1031
- };
1032
- },
1033
-
1034
- /**
1035
- * Template for this view
1036
- */
1037
- template: wp.media.template('easingslider-slide'),
1038
-
1039
- /**
1040
- * Constructor
1041
- */
1042
- initialize: function() {
1043
-
1044
- // Bind events
1045
- this.model.on('change', this._setData, this);
1046
- this.model.on('change:id', this._updateID, this);
1047
- this.model.on('change:url', this.render, this);
1048
- this.model.on('change:poster', this.render, this);
1049
- this.model.on('change:attachment_id', this.render, this);
1050
-
1051
- // Bind additional attachment events if appropriate
1052
- if ( this.model.attachment ) {
1053
- this.model.attachment.on('change', this.render, this);
1054
- }
1055
-
1056
- },
1057
-
1058
- /**
1059
- * Sets our data
1060
- */
1061
- _setData: function() {
1062
-
1063
- // Set data in hidden input
1064
- this.$('input[name="slides[]"]').val(JSON.stringify(this.model.attributes));
1065
-
1066
- },
1067
-
1068
- /**
1069
- * Update our ID attribute
1070
- */
1071
- _updateID: function(model, value) {
1072
-
1073
- // Update attrbitue on DOM
1074
- this.$el.attr('data-id', value);
1075
-
1076
- // Update attribute on view object
1077
- this.attributes['data-id'] = value;
1078
-
1079
- },
1080
-
1081
- /**
1082
- * Renders the view
1083
- */
1084
- render: function() {
1085
-
1086
- var data = { model: this.model.toJSON() };
1087
-
1088
- // If our model has an attachment, add it to the data.
1089
- if ( this.model.attachment ) {
1090
- data.attachment = this.model.attachment.toJSON();
1091
- }
1092
-
1093
- // Generate the template
1094
- this.$el.html(this.template(data));
1095
-
1096
- return this;
1097
-
1098
- }
1099
-
1100
- });
1101
-
1102
- /**
1103
- * Our "Add Slide" views for various slide types
1104
- */
1105
- Editor.views.AddSlide = {
1106
-
1107
- /**
1108
- * Returns the appropriate "Add Slide" view, based on the type of slide provided
1109
- */
1110
- get: function(options) {
1111
- return new Editor.views.AddSlide[options.type](options);
1112
- }
1113
-
1114
- };
1115
-
1116
- /**
1117
- * Our "Add Slide" view for images
1118
- */
1119
- Editor.views.AddSlide.image = wp.media.view.AttachmentsBrowser.extend();
1120
-
1121
- /**
1122
- * Our "Edit Slide" views for various slide types
1123
- */
1124
- Editor.views.EditSlide = {
1125
-
1126
- /**
1127
- * Returns the appropriate "Edit Slide" view, based on the type of slide provided
1128
- */
1129
- get: function(options) {
1130
- return new Editor.views.EditSlide[options.type](options);
1131
- }
1132
-
1133
- };
1134
-
1135
- /**
1136
- * "Edit Slide" view for images
1137
- */
1138
- Editor.views.EditSlide.image = wp.media.view.ImageDetails.extend({
1139
-
1140
- /**
1141
- * Classname
1142
- */
1143
- className: 'edit-attachment-frame attachment-details mode-select',
1144
-
1145
- /**
1146
- * Template for this view
1147
- */
1148
- template: wp.media.template('easingslider-edit-slide'),
1149
-
1150
- /**
1151
- * Constructor
1152
- */
1153
- initialize: function() {
1154
-
1155
- console.log(this.model.get('linkTargetBlank'));
1156
-
1157
- // Call parent constructor
1158
- wp.media.view.ImageDetails.prototype.initialize.apply(this, arguments);
1159
-
1160
- // Bind events
1161
- this.model.on('change:url', this._updateImage, this);
1162
-
1163
- },
1164
-
1165
- /**
1166
- * Updates the image preview (URL images only)
1167
- */
1168
- _updateImage: function() {
1169
-
1170
- this.$('.details-image').attr('src', this.model.get('url'));
1171
-
1172
- }
1173
-
1174
- });
1175
-
1176
- /**
1177
- * Router
1178
- */
1179
- Editor.router = Backbone.Router.extend({
1180
-
1181
- /**
1182
- * Routes
1183
- */
1184
- routes: {
1185
- 'admin.php?page=:page&edit=:id&change=:slide': 'changeSlide',
1186
- 'admin.php?page=:page&edit=:id&slide=:slide': 'editSlide',
1187
- 'admin.php?page=:page&edit=:id': 'edit',
1188
- 'admin.php?page=easingslider_publish_slider': 'edit'
1189
- },
1190
-
1191
- /**
1192
- * Shows the change slide editor within the admin editor
1193
- */
1194
- changeSlide: function(page, id, slide) {
1195
-
1196
- // Load the admin view
1197
- this.edit();
1198
-
1199
- // Once the colleciton has been synced, open the edit slide frame
1200
- this.AdminView.collection.on('sync:done', function() {
1201
- this.AdminView.openChangeSlideFrame(slide);
1202
- }, this);
1203
-
1204
- return this;
1205
-
1206
- },
1207
-
1208
- /**
1209
- * Shows the slide editor within the admin editor
1210
- */
1211
- editSlide: function(page, id, slide) {
1212
-
1213
- // Load the admin view
1214
- this.edit();
1215
-
1216
- // Once the colleciton has been synced, open the edit slide frame
1217
- this.AdminView.collection.on('sync:done', function() {
1218
- this.AdminView.openEditSlideFrame(slide);
1219
- }, this);
1220
-
1221
- return this;
1222
-
1223
- },
1224
-
1225
- /**
1226
- * Shows the admin editor
1227
- */
1228
- edit: function(page) {
1229
-
1230
- // Bail if we don't have slides
1231
- if ( ! window.slides ) {
1232
- return this;
1233
- }
1234
-
1235
- // Initate our admin view
1236
- this.AdminView = new Editor.views.Admin({
1237
- collection: new Editor.collections.Slides(JSON.parse(window.slides))
1238
- });
1239
-
1240
- // Sync the collection & get the ball rolling!
1241
- this.AdminView.collection.sync();
1242
-
1243
- return this;
1244
-
1245
- }
1246
-
1247
- });
1248
-
1249
- /**
1250
- * Let's go!
1251
- */
1252
- $(document).ready(function() {
1253
-
1254
- // Initiate the router
1255
- Editor.Router = new Editor.router();
1256
-
1257
- // Start the history
1258
- Backbone.history.start({
1259
- root: window._wpMediaGridSettings.adminUrl,
1260
- pushState: true,
1261
- });
1262
-
1263
- // Handly delete class
1264
- $('.delete').each(function() {
1265
- $(this).on('click', function() {
1266
- if ( ! confirm( _easingsliderEditorL10n.warn ) ) {
1267
- return false;
1268
- }
1269
- });
1270
- });
1271
-
1272
- });
1273
-
1274
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/editor-pages.min.js DELETED
@@ -1 +0,0 @@
1
- window.EasingSlider=window.EasingSlider||{Editor:{models:{},collections:{},controllers:{},frames:{},views:{},router:{},Router:{}}},function(e){var t=window.EasingSlider.Editor;t.models.Slide={get:function(e){return new t.models.Slide[e.type](e)}},t.models.Slide.image=Backbone.Model.extend({attachment:!1,defaults:_.defaults({attachment_id:null,type:"image",alt:"",aspectRatio:null,link:"none",linkUrl:"",linkTargetBlank:!1,title:"",url:null},wp.media.model.PostImage.prototype.defaults)}),t.collections.Slides=Backbone.Collection.extend({model:t.models.Slide.get,initialize:function(){this.on("add",this._resetIDs,this),this.on("remove",this._resetIDs,this),this.on("reset",this._resetIDs,this)},comparator:function(e){return e.get("id")},_resetIDs:function(){var e=new Backbone.Collection;_.each(this.models,function(t,i){t.set({id:i+1}),e.add(t)}),this.reset(e.models,{silent:!0})},reposition:function(e,t){return this.remove(e,{silent:!0}),this.add(e,{at:t,silent:!0}),this._resetIDs(),this},sync:function(){var e=this,t=[];_.each(this.models,function(e){e.has("attachment_id")&&t.push(e.get("attachment_id"))},this);var i=wp.media.query({post__in:t,posts_per_page:-1});return i.more().done(function(){_.each(i.models,function(t){var i=e.where({attachment_id:t.get("id")});_.each(i,function(e){e.attachment=t})}),e.trigger("sync:done")}),this}}),t.controllers.AddSlide={get:function(e){return new t.controllers.AddSlide[e.type](e)}},t.controllers.AddSlide.image=wp.media.controller.Library.extend(),t.controllers.EditSlide={get:function(e){return new t.controllers.EditSlide[e.type](e)}},t.controllers.EditSlide.image=wp.media.controller.ImageDetails.extend({defaults:_.defaults({id:"edit-slide",title:_easingsliderEditorL10n.media_upload.title},wp.media.controller.ImageDetails.prototype.defaults)}),t.frames.AddSlide=wp.media.view.MediaFrame.Post.extend({initialize:function(){_.defaults(this.options,{multiple:!0}),wp.media.view.MediaFrame.Post.prototype.initialize.apply(this,arguments),this.on("content:render:browse",this.removeSidebar,this),this.on("toolbar:create:insert-slide",this.createToolbar,this),this.on("toolbar:render:insert-slide",this.insertToolbar,this)},browseContent:function(e){var i=this.state();this.$el.removeClass("hide-toolbar"),e.view=new t.views.AddSlide.image({controller:this,collection:i.get("library"),selection:i.get("selection"),model:i,sortable:i.get("sortable"),search:i.get("searchable"),filters:i.get("filterable"),date:i.get("date"),display:i.get(i.has("display")?"display":"displaySettings"),dragInfo:i.get("dragInfo"),idealColumnWidth:i.get("idealColumnWidth"),suggestedWidth:i.get("suggestedWidth"),suggestedHeight:i.get("suggestedHeight"),AttachmentView:i.get("AttachmentView")})},createStates:function(){this.states.add([new t.controllers.AddSlide.image({id:"insert",type:"image",title:_easingsliderEditorL10n.media_upload.image_from_media,priority:20,toolbar:"insert-slide",filterable:!1,library:wp.media.query({type:"image"}),multiple:!0,editable:!0,allowLocalEdits:!0,displaySettings:!1,displayUserSettings:!0})])},removeSidebar:function(e){e.sidebar.remove("details"),e.$el.addClass("hide-sidebar")},insertToolbar:function(e){var t=this;e.set("insert-slide",{style:"primary",priority:80,text:_easingsliderEditorL10n.media_upload.insert_into_slider,requires:{selection:!1},click:function(){t.close().trigger("insert",t.getSelection()).reset()}})},getSelection:function(e){var i=new wp.media.model.Selection(null,{multiple:!0}),s=this.state().get("type"),e=this.state().get("selection");return _.each(e.models,function(e){var n=new t.models.Slide.get({type:s});e.get("id")?(n.attachment=e,n.set({attachment_id:e.get("id")},{silent:!0})):n.set(e,{silent:!0}),i.add(n)},this),i}}),t.frames.EditSlide={get:function(e){return new(t.frames.EditSlide[e.model.get("type")])(e)}},t.frames.EditSlide.image=wp.media.view.MediaFrame.ImageDetails.extend({initialize:function(){this.image=new wp.media.model.PostImage(this.model.attributes),this.options.state="edit-slide",this.options.selection=new wp.media.model.Selection(this.image.attachment,{multiple:!1}),wp.media.view.MediaFrame.Select.prototype.initialize.apply(this,arguments),this.on("content:render:browse",this.removeSidebar,this),this.state("edit-slide").on("update",this.updateSettings,this),this.state("replace-image").on("replace",this.replaceImage,this)},createStates:function(){this.states.add([new t.controllers.EditSlide.get({type:"image",image:this.image,editable:!1})]),wp.media.view.MediaFrame.ImageDetails.prototype.createStates.apply(this,arguments)},imageDetailsContent:function(e){e.view=new t.views.EditSlide.get({type:"image",controller:this,model:this.state().image,attachment:this.state().image.attachment})},removeSidebar:function(e){e.sidebar.remove("details"),e.$el.addClass("hide-sidebar")},updateSettings:function(){var e={};this.$("*[data-setting]").each(function(){e[this.dataset.setting]="checkbox"==this.type?this.checked?this.value:!1:this.value}),this.model.set(e)},replaceImage:function(){this.model.set({attachment_id:this.image.attachment.id}),this.model.attachment.set(this.image.attachment.attributes)}}),t.views.Admin=Backbone.View.extend({el:".wrap",events:{"click #add-slides":"_addSlide","click #select-all":"_selectAll","click #delete-slides":"_clickBulkDelete","click #save":"_clickSave","click .toolbar .edit":"_clickEdit","click .toolbar .remove":"_clickDelete","click .show-advanced-options":"_clickAdvancedOptions","click .thumbnail":"_clickThumb","click .select-mode-toggle-button":"_toggleMode","click .sidebar-name":"_toggleWidget"},initialize:function(){this.subviews={AddSlide:new t.frames.AddSlide,AdminSlides:new t.views.AdminSlides({collection:this.collection})},this.collection.on("sync:done",this.render,this),this.collection.on("sync:done",this._enableSave,this),this.subviews.AddSlide.on("insert",this._handleInsert,this),e(window).on("resize",this._setColumns.bind(this)),this._selectMode=!1,this._setColumns(),this._showSpinner()},_showSpinner:function(){this.$("#slides-browser").append('<div class="spinner"></div>')},_hideSpinner:function(){this.$("#slides-browser .spinner").remove()},_enableSave:function(){this.$("#save").prop("disabled",!1)},_clickSave:function(){this.$("#publishing-action .spinner").css({display:"block"})},_setColumns:function(){var e=this.$(".media-frame-content"),t=e.attr("data-columns"),i=e.width();if(i){var s=Math.min(Math.round(i/145),12)||1;t&&t===s||e.attr("data-columns",s)}},_handleInsert:function(e){this.collection.add(e.models)},_clickThumb:function(e){e.preventDefault(),this._selectMode?this._toggleSelect(e):this._editSlide(e)},_clickEdit:function(e){e.preventDefault(),this._editSlide(e)},_clickDelete:function(t){if(t.preventDefault(),confirm(_easingsliderEditorL10n.warn)){var i=e(t.currentTarget).parents(".attachment").attr("data-id");this.collection.remove(i)}},_clickBulkDelete:function(e){e.preventDefault(),confirm(_easingsliderEditorL10n.warn)&&(this._deleteSlides(e),this._toggleMode(e))},_clickAdvancedOptions:function(t){t.preventDefault();var i=e(t.currentTarget).parent().find(".advanced-options");i.toggleClass("hidden")},_toggleMode:function(e){e.preventDefault(),this._selectMode=this._selectMode?!1:!0,this.$(".attachment").removeClass("selected details"),this.$(".media-frame").toggleClass("mode-select"),this.$(".media-toolbar div *").toggleClass("hidden")},_toggleSelect:function(t){t.preventDefault(),e(t.currentTarget).parents(".attachment").toggleClass("selected details")},_toggleWidget:function(t){t.preventDefault();var i=e(t.currentTarget).parent(),s=i.find(".sidebar-content");i.hasClass("fixed")||(this.$(".widgets-holder-wrap").each(function(){var t=e(this);t.hasClass("fixed")||t.find(".sidebar-content").slideUp(200,function(){t.addClass("closed")})}),i.hasClass("closed")&&s.slideDown(200,function(){i.removeClass("closed")}))},_selectAll:function(e){e.preventDefault(),this.$(".attachment").addClass("selected details")},_deleteSlides:function(t){t.preventDefault();var i=this.collection,s=[];this.$(".attachment").each(function(t){e(this).hasClass("selected")&&s.push(i.at(t))}),this.collection.remove(s)},_addSlide:function(e){e.preventDefault(),this.addSlide()},addSlide:function(){return this.subviews.AddSlide.open(),this},_editSlide:function(t){t.preventDefault();var i=e(t.currentTarget).parents(".attachment").attr("data-id");this.editSlide(i)},editSlide:function(e){return this.subviews.EditSlide=new t.frames.EditSlide.get({model:this.collection.get(e)}),this.subviews.EditSlide.open(),this},render:function(){this._hideSpinner();var e=this.subviews.AdminSlides.render().el;return this.$("#slides-browser").append(e),this}}),t.views.AdminSlides=Backbone.View.extend({tagName:"ul",attributes:{"class":"attachments ui-sortable",tabindex:"-1"},initialize:function(){this.subviews=[],this.collection.on("add",this.add,this),this.collection.on("remove",this.render,this),this.collection.on("reset",this.render,this),this.$el.sortable({items:".attachment",containment:"parent",tolerance:"pointer",stop:this._sort.bind(this)})},_sort:function(e,t){var i=this.collection.get(t.item.context.dataset.id);this.collection.reposition(i,t.item.index())},add:function(e){var i=new t.views.AdminSlide({model:e});return this.subviews.push(i),this.$el.append(i.render().$el),this},render:function(){return this.subviews=[],this.$el.empty(),_.each(this.collection.models,function(e){this.add(e)},this),this}}),t.views.AdminSlide=Backbone.View.extend({tagName:"li",attributes:function(){return{role:"checkbox","class":"attachment save-ready",tabindex:"0","data-id":this.model.id}},template:wp.media.template("easingslider-slide"),initialize:function(){this.model.on("change",this._setData,this),this.model.on("change:id",this._updateID,this),this.model.on("change:url",this.render,this),this.model.on("change:poster",this.render,this),this.model.on("change:attachment_id",this.render,this),this.model.attachment&&this.model.attachment.on("change",this.render,this)},_setData:function(){this.$('input[name="slides[]"]').val(JSON.stringify(this.model.attributes))},_updateID:function(e,t){this.$el.attr("data-id",t),this.attributes["data-id"]=t},render:function(){var e={model:this.model.toJSON()};return this.model.attachment&&(e.attachment=this.model.attachment.toJSON()),this.$el.html(this.template(e)),this}}),t.views.AddSlide={get:function(e){return new t.views.AddSlide[e.type](e)}},t.views.AddSlide.image=wp.media.view.AttachmentsBrowser.extend(),t.views.EditSlide={get:function(e){return new t.views.EditSlide[e.type](e)}},t.views.EditSlide.image=wp.media.view.ImageDetails.extend({className:"edit-attachment-frame attachment-details mode-select",template:wp.media.template("easingslider-edit-slide"),initialize:function(){console.log(this.model.get("linkTargetBlank")),wp.media.view.ImageDetails.prototype.initialize.apply(this,arguments),this.model.on("change:url",this._updateImage,this)},_updateImage:function(){this.$(".details-image").attr("src",this.model.get("url"))}}),t.router=Backbone.Router.extend({routes:{"admin.php?page=:page&edit=:id&change=:slide":"changeSlide","admin.php?page=:page&edit=:id&slide=:slide":"editSlide","admin.php?page=:page&edit=:id":"edit","admin.php?page=easingslider_publish_slider":"edit"},changeSlide:function(e,t,i){return this.edit(),this.AdminView.collection.on("sync:done",function(){this.AdminView.openChangeSlideFrame(i)},this),this},editSlide:function(e,t,i){return this.edit(),this.AdminView.collection.on("sync:done",function(){this.AdminView.openEditSlideFrame(i)},this),this},edit:function(){return window.slides?(this.AdminView=new t.views.Admin({collection:new t.collections.Slides(JSON.parse(window.slides))}),this.AdminView.collection.sync(),this):this}}),e(document).ready(function(){t.Router=new t.router,Backbone.history.start({root:window._wpMediaGridSettings.adminUrl,pushState:!0}),e(".delete").each(function(){e(this).on("click",function(){return confirm(_easingsliderEditorL10n.warn)?void 0:!1})})})}(jQuery);
 
js/jquery.easingslider.js DELETED
@@ -1,593 +0,0 @@
1
- ;(function($) {
2
-
3
- /**
4
- * jQuery Slider
5
- */
6
- $.EasingSlider = function(el) {
7
-
8
- // Core variables
9
- var base = this,
10
- o;
11
-
12
- // Establish our elements
13
- base.el = el;
14
- base.$el = $(base.el);
15
- base.$viewport = base.$el.find('.easingslider-viewport');
16
- base.$slides = base.$el.find('.easingslider-slide');
17
- base.$arrows = base.$el.find('.easingslider-arrows');
18
- base.$next = base.$el.find('.easingslider-next');
19
- base.$prev = base.$el.find('.easingslider-prev');
20
- base.$pagination = base.$el.find('.easingslider-pagination');
21
- base.$icons = base.$el.find('.easingslider-icon');
22
- base.$preload = base.$el.find('.easingslider-preload');
23
-
24
- // Get the plugin options
25
- base.options = o = $.extend({}, $.EasingSlider.defaults, $.parseJSON(base.$el.attr('data-options')));
26
-
27
- // State variables
28
- base.current = 0;
29
- base.previous = 0;
30
- base.count = base.$slides.length;
31
- base.width = o.dimensions.width;
32
- base.height = o.dimensions.height;
33
-
34
- // Store our data
35
- base.$el.data('easingslider', base);
36
-
37
- /**
38
- * Constructor
39
- */
40
- base.initialize = function() {
41
-
42
- // Determine click event
43
- base._clickEvent = ( 'ontouchstart' in document.documentElement ) ? 'touchstart' : 'click';
44
-
45
- // Hide all slides
46
- base.$slides.css({ 'display': 'none' });
47
-
48
- // Set the current slide
49
- base.$slides.eq(base.current).css({ 'display': 'block' }).addClass('active');
50
-
51
- // Setup components
52
- base._setupArrows();
53
- base._setupPagination();
54
- base._setupPlayback();
55
- base._setupResizing();
56
- base._setupBackgrounds();
57
-
58
- // Preload the slider
59
- base._preload();
60
-
61
- // Trigger event
62
- base.$el.trigger('init', base);
63
-
64
- return base;
65
-
66
- };
67
-
68
- /**
69
- * Sets up the "Arrow" navigation
70
- */
71
- base._setupArrows = function() {
72
-
73
- // Continue if arrows are enabled
74
- if ( o.navigation.arrows ) {
75
-
76
- // "Next" & "Previous" arrow functionality
77
- base.$next.bind(base._clickEvent, base.nextSlide);
78
- base.$prev.bind(base._clickEvent, base.prevSlide);
79
-
80
- // Add hover toggle if enabled
81
- if ( o.navigation.arrows_hover ) {
82
- base.$arrows.addClass('has-hover');
83
- }
84
-
85
- // Show the arrows
86
- base.$arrows.css({ 'display': 'block' });
87
-
88
- }
89
-
90
- return base;
91
-
92
- };
93
-
94
- /**
95
- * Sets up the "Pagination" navigation
96
- */
97
- base._setupPagination = function() {
98
-
99
- // Continue if pagination is enabled
100
- if ( o.navigation.pagination ) {
101
-
102
- // Bind events
103
- base.$el.bind('loaded', base._updatePagination);
104
- base.$el.bind('transition.before', base._updatePagination);
105
-
106
- // Enable click event for each icon
107
- base.$icons.bind(base._clickEvent, function() {
108
-
109
- // Get the next slide index and direction we are travelling
110
- var eq = $(this).index(),
111
- direction = (eq > base.current) ? 'forward' : 'backward';
112
-
113
- // Transition to the desired slide
114
- base.goToSlide(eq, direction);
115
-
116
- });
117
-
118
- // Add hover toggle if enabled
119
- if ( o.navigation.pagination_hover ) {
120
- base.$pagination.addClass('has-hover');
121
- }
122
-
123
- // Show the pagination
124
- base.$pagination.css({ 'display': 'block' });
125
-
126
- }
127
-
128
- return base;
129
-
130
- };
131
-
132
- /**
133
- * Updates the active pagination icon
134
- */
135
- base._updatePagination = function() {
136
-
137
- // Continue if pagination is enabled
138
- if ( o.navigation.pagination ) {
139
-
140
- // Update the active icon
141
- base.$icons.removeClass('active').eq(base.current).addClass('active');
142
-
143
- }
144
-
145
- return base;
146
-
147
- };
148
-
149
- /**
150
- * Sets up the automatic playback
151
- */
152
- base._setupPlayback = function() {
153
-
154
- // Clear playback timer before the transition. It'll be reset after the transition has completed.
155
- base.$el.bind('transition.before', function() {
156
- if ( base._playbackTimer ) {
157
- clearTimeout(base._playbackTimer);
158
- }
159
- });
160
-
161
- // Once a transition has completed, continue playback if we have an active timer.
162
- base.$el.bind('transition.after', function() {
163
- if ( base._playbackTimer ) {
164
- base.startPlayback();
165
- }
166
- });
167
-
168
- // Queue playback after the slider has loaded, if enabled.
169
- if ( o.playback.enabled && base.count > 1 ) {
170
- base.$el.bind('loaded', base.startPlayback);
171
- }
172
-
173
- return base;
174
-
175
- };
176
-
177
- /**
178
- * Sets up the responsive support
179
- */
180
- base._setupResizing = function() {
181
-
182
- // Continue if responsive is enabled
183
- if ( o.dimensions.responsive ) {
184
-
185
- // Update the size
186
- base._updateSize();
187
-
188
- // Handle window resizing
189
- $(window).bind('resize', base._updateSize);
190
-
191
- }
192
-
193
- return base;
194
-
195
- };
196
-
197
- /**
198
- * Updates the slider's size
199
- */
200
- base._updateSize = function() {
201
-
202
- // Get the container width
203
- var width = base.$el.outerWidth();
204
-
205
- // If it has changed, resize the height to match.
206
- if ( width <= base.width && o.dimensions.keep_ratio ) {
207
-
208
- // Using the default slider width, let's calculate the percentage change and thus calculate the new height.
209
- var height = Math.floor((width / base.width) * base.height);
210
-
211
- // Set the viewport height
212
- base.$viewport.css({ 'height': height +'px' });
213
-
214
- // Trigger event
215
- base.$el.trigger('size.update', [base, width, height]);
216
-
217
- }
218
-
219
- return base;
220
-
221
- };
222
-
223
- /**
224
- * Sets up the background slides, if enabled
225
- */
226
- base._setupBackgrounds = function() {
227
-
228
- // Handle background images, if enabled
229
- if ( o.dimensions.background_images ) {
230
- base.$slides.each(function() {
231
-
232
- // Establish variables
233
- var $slide = $(this),
234
- $image = $slide.find('.easingslider-image');
235
-
236
- // Set background
237
- $slide.addClass('easingslider-background-slide').css({ 'background-image': 'url('+ $image.attr('src') +')' });
238
-
239
- // Hide slide image
240
- $image.css({ 'display': 'none' });
241
-
242
- });
243
- }
244
-
245
- };
246
-
247
- /**
248
- * Preloads the slider
249
- */
250
- base._preload = function() {
251
-
252
- // Get the total number of images
253
- var total_images = base.$slides.find('.easingslider-image').length;
254
-
255
- // Preloaded slide count
256
- base._preloadCount = 0;
257
-
258
- // Loop through and preload each image slide. Doesn't stop on failure, just continues instead.
259
- base.$el.find('.easingslider-image').each(function() {
260
-
261
- // Load the image
262
- $(this).one('load', function() {
263
-
264
- // If all slides have been preloaded, hide the preloader and start the playback. Also increase preloader count.
265
- if ( ++base._preloadCount == total_images ) {
266
- base.$preload.animate({ 'opacity': 0 }, {
267
- duration: 400,
268
- complete: function() {
269
-
270
- // Remove preloader
271
- $(this).remove();
272
-
273
- // Flag as loaded
274
- base.$el.addClass('has-loaded');
275
-
276
- // Trigger events
277
- base.$el.trigger('loaded', base);
278
-
279
- }
280
- });
281
- }
282
-
283
- }).each(function() {
284
-
285
- // Load on complete
286
- if ( this.complete ) {
287
- $(this).load();
288
- }
289
-
290
- });
291
-
292
- });
293
-
294
- };
295
-
296
- /**
297
- * Handles slide preloading
298
- */
299
- base._load = function() {
300
-
301
- // Increase preloaded count
302
- base._preloadCount++;
303
-
304
- // Get the total number of images
305
- var total_images = base.$slides.find('.easingslider-image').length;
306
-
307
- // If all slides have been preloaded, hide the preloader and start the playback.
308
- if ( base._preloadCount == total_images ) {
309
- base.$preload.animate({ 'opacity': 0 }, {
310
- duration: 400,
311
- complete: function() {
312
-
313
- // Remove preloader
314
- $(this).remove();
315
-
316
- // Flag as loaded
317
- base.$el.addClass('has-loaded');
318
-
319
- // Trigger events
320
- base.$el.trigger('loaded', base);
321
-
322
- }
323
- });
324
- }
325
-
326
- };
327
-
328
- /**
329
- * Starts automatic playback
330
- */
331
- base.startPlayback = function() {
332
-
333
- // Runtime variable
334
- base._runtime = new Date();
335
-
336
- // Get pause time
337
- base._pauseTime = o.playback.pause;
338
-
339
- // Start automatic playback
340
- base._playbackTimer = setTimeout(function() {
341
- base.nextSlide();
342
- }, base._pauseTime);
343
-
344
- // Trigger event
345
- base.$el.trigger('playback.start', base);
346
-
347
- return base;
348
-
349
- };
350
-
351
- /**
352
- * Ends automatic playback
353
- */
354
- base.endPlayback = function() {
355
-
356
- // Clear playback timer
357
- clearTimeout(base._playbackTimer);
358
-
359
- // Set timer to flase
360
- base._playbackTimer = false;
361
-
362
- // Trigger event
363
- base.$el.trigger('playback.end', base);
364
-
365
- return base;
366
-
367
- };
368
-
369
- /**
370
- * Pauses automatic playback
371
- */
372
- base.pausePlayback = function() {
373
-
374
- // Clear playback timer
375
- clearTimeout(base._playbackTimer);
376
-
377
- // Calculate runtime left
378
- base._runtime = Math.ceil(new Date() - base._runtime);
379
-
380
- // Trigger event
381
- base.$el.trigger('playback.pause', base);
382
-
383
- return base;
384
-
385
- };
386
-
387
- /**
388
- * Resumes automatic playback
389
- */
390
- base.resumePlayback = function() {
391
-
392
- // Calculate playback time remaining
393
- base._pauseTime = Math.ceil(base._pauseTime - base._runtime);
394
-
395
- // Reset runtime
396
- base._runtime = new Date();
397
-
398
- // Resume automatic playback
399
- base._playbackTimer = setTimeout(function() {
400
- base.nextSlide();
401
- }, base._pauseTime);
402
-
403
- // Trigger event
404
- base.$el.trigger('playback.resume', base);
405
-
406
- return base;
407
-
408
- };
409
-
410
- /**
411
- * Executes a transition
412
- */
413
- base._transition = function(eq, direction) {
414
-
415
- // Bail if we only have one slide
416
- if ( base.count <= 1 ) {
417
- return base;
418
- }
419
-
420
- // Bail if specified slide doesn't exist
421
- if ( base.$slides.eq(eq).length == 0 ) {
422
- return base;
423
- }
424
-
425
- // Bail if animating already
426
- if ( base._animating ) {
427
- return base;
428
- }
429
-
430
- // Flag that we are transitioning
431
- base._animating = true;
432
-
433
- // Establish the next and previous slides
434
- base.previous = base.current;
435
- base.current = eq;
436
-
437
- /**
438
- * Add animation classes based on direction.
439
- *
440
- * Timeout functions are used here to avoid a bug in Safari.
441
- * The animations won't work if we toggle the display property as we add the animation class,
442
- * instead it would intermittently show/hide the slide.
443
- *
444
- * Using a timeout seems to negate this.
445
- */
446
- if ( 'backward' == direction ) {
447
- base.$slides.eq(base.previous).css({ 'display': 'block' });
448
- base.$slides.eq(base.current).css({ 'display': 'block' });
449
-
450
- setTimeout(function() {
451
- base.$slides.eq(base.previous).addClass('next-out');
452
- base.$slides.eq(base.current).addClass('prev-in');
453
- });
454
- }
455
- else {
456
- base.$slides.eq(base.previous).css({ 'display': 'block' });
457
- base.$slides.eq(base.current).css({ 'display': 'block' });
458
-
459
- setTimeout(function() {
460
- base.$slides.eq(base.previous).addClass('prev-out');
461
- base.$slides.eq(base.current).addClass('next-in');
462
- });
463
- }
464
-
465
- // After timeout, do some cleaning up.
466
- clearTimeout(base._cleanup);
467
- base._cleanup = setTimeout(function() {
468
-
469
- // Toggle the active slide
470
- base.$slides.eq(base.current).css({ 'display': 'block' }).addClass('active');
471
- base.$slides.eq(base.previous).css({ 'display': 'none' }).removeClass('active');
472
-
473
- // Remove all animation related classes
474
- base.$slides.removeClass('next-in next-out prev-in prev-out');
475
-
476
- // Flag that we are no longer animating
477
- base._animating = false;
478
-
479
- // Trigger event
480
- base.$el.trigger('transition.after', [ base, eq, direction ]);
481
-
482
- }, o.transitions.duration);
483
-
484
- // Trigger event
485
- base.$el.trigger('transition.before', [ base, eq, direction ]);
486
-
487
- return base;
488
-
489
- };
490
-
491
- /**
492
- * Transitions to the next slide
493
- */
494
- base.nextSlide = function() {
495
-
496
- // Establish the next slide
497
- var eq = ( base.current == (base.count - 1) ) ? 0 : (base.current + 1);
498
-
499
- // Transition to the next slide
500
- base._transition(eq, 'forward');
501
-
502
- // Trigger event
503
- base.$el.trigger('transition.next', [ base, eq, 'forward' ]);
504
-
505
- return base;
506
-
507
- };
508
-
509
- /**
510
- * Transitions to the previous slide
511
- */
512
- base.prevSlide = function() {
513
-
514
- // Establish the previous slide
515
- var eq = ( base.current == 0 ) ? (base.count - 1) : (base.current - 1);
516
-
517
- // Transition to the previous slide
518
- base._transition(eq, 'backward');
519
-
520
- // Trigger event
521
- base.$el.trigger('transition.prev', [ base, eq, 'backward' ]);
522
-
523
- return base;
524
-
525
- };
526
-
527
- /**
528
- * Transitions to a specified slide
529
- */
530
- base.goToSlide = function(eq, direction) {
531
-
532
- // Transition to the specified slide
533
- this._transition(eq, direction);
534
-
535
- // Trigger event
536
- base.$el.trigger('transition.to', [ base, eq, direction ]);
537
-
538
- return base;
539
-
540
- };
541
-
542
- // Initialize the plugin
543
- base.initialize();
544
-
545
- };
546
-
547
- /**
548
- * Plugin defaults settings
549
- */
550
- $.EasingSlider.defaults = {
551
- dimensions: {
552
- width: 640,
553
- height: 400,
554
- responsive: true,
555
- full_width: false,
556
- image_resizing: false,
557
- keep_ratio: true,
558
- background_images: false
559
- },
560
- transitions: {
561
- effect: 'fade',
562
- duration: 400
563
- },
564
- navigation: {
565
- arrows: true,
566
- arrows_hover: false,
567
- arrows_position: 'inside',
568
- pagination: true,
569
- pagination_hover: false,
570
- pagination_position: 'inside',
571
- pagination_location: 'bottom-center'
572
- },
573
- playback: {
574
- enabled: true,
575
- pause: 4000
576
- }
577
- };
578
-
579
- /**
580
- * Initiates slider(s)
581
- */
582
- $.fn.EasingSlider = function() {
583
- return this.each(function() {
584
- new $.EasingSlider(this);
585
- });
586
- };
587
-
588
- // Let's go!
589
- $(document).ready(function() {
590
- $('.easingslider').EasingSlider();
591
- });
592
-
593
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/jquery.easingslider.min.js DELETED
@@ -1 +0,0 @@
1
- !function(e){e.EasingSlider=function(i){var n,a=this;a.el=i,a.$el=e(a.el),a.$viewport=a.$el.find(".easingslider-viewport"),a.$slides=a.$el.find(".easingslider-slide"),a.$arrows=a.$el.find(".easingslider-arrows"),a.$next=a.$el.find(".easingslider-next"),a.$prev=a.$el.find(".easingslider-prev"),a.$pagination=a.$el.find(".easingslider-pagination"),a.$icons=a.$el.find(".easingslider-icon"),a.$preload=a.$el.find(".easingslider-preload"),a.options=n=e.extend({},e.EasingSlider.defaults,e.parseJSON(a.$el.attr("data-options"))),a.current=0,a.previous=0,a.count=a.$slides.length,a.width=n.dimensions.width,a.height=n.dimensions.height,a.$el.data("easingslider",a),a.initialize=function(){return a._clickEvent="ontouchstart"in document.documentElement?"touchstart":"click",a.$slides.css({display:"none"}),a.$slides.eq(a.current).css({display:"block"}).addClass("active"),a._setupArrows(),a._setupPagination(),a._setupPlayback(),a._setupResizing(),a._setupBackgrounds(),a._preload(),a.$el.trigger("init",a),a},a._setupArrows=function(){return n.navigation.arrows&&(a.$next.bind(a._clickEvent,a.nextSlide),a.$prev.bind(a._clickEvent,a.prevSlide),n.navigation.arrows_hover&&a.$arrows.addClass("has-hover"),a.$arrows.css({display:"block"})),a},a._setupPagination=function(){return n.navigation.pagination&&(a.$el.bind("loaded",a._updatePagination),a.$el.bind("transition.before",a._updatePagination),a.$icons.bind(a._clickEvent,function(){var i=e(this).index(),n=i>a.current?"forward":"backward";a.goToSlide(i,n)}),n.navigation.pagination_hover&&a.$pagination.addClass("has-hover"),a.$pagination.css({display:"block"})),a},a._updatePagination=function(){return n.navigation.pagination&&a.$icons.removeClass("active").eq(a.current).addClass("active"),a},a._setupPlayback=function(){return a.$el.bind("transition.before",function(){a._playbackTimer&&clearTimeout(a._playbackTimer)}),a.$el.bind("transition.after",function(){a._playbackTimer&&a.startPlayback()}),n.playback.enabled&&a.count>1&&a.$el.bind("loaded",a.startPlayback),a},a._setupResizing=function(){return n.dimensions.responsive&&(a._updateSize(),e(window).bind("resize",a._updateSize)),a},a._updateSize=function(){var e=a.$el.outerWidth();if(e<=a.width&&n.dimensions.keep_ratio){var i=Math.floor(e/a.width*a.height);a.$viewport.css({height:i+"px"}),a.$el.trigger("size.update",[a,e,i])}return a},a._setupBackgrounds=function(){n.dimensions.background_images&&a.$slides.each(function(){var i=e(this),n=i.find(".easingslider-image");i.addClass("easingslider-background-slide").css({"background-image":"url("+n.attr("src")+")"}),n.css({display:"none"})})},a._preload=function(){var i=a.$slides.find(".easingslider-image").length;a._preloadCount=0,a.$el.find(".easingslider-image").each(function(){e(this).one("load",function(){++a._preloadCount==i&&a.$preload.animate({opacity:0},{duration:400,complete:function(){e(this).remove(),a.$el.addClass("has-loaded"),a.$el.trigger("loaded",a)}})}).each(function(){this.complete&&e(this).load()})})},a._load=function(){a._preloadCount++;var i=a.$slides.find(".easingslider-image").length;a._preloadCount==i&&a.$preload.animate({opacity:0},{duration:400,complete:function(){e(this).remove(),a.$el.addClass("has-loaded"),a.$el.trigger("loaded",a)}})},a.startPlayback=function(){return a._runtime=new Date,a._pauseTime=n.playback.pause,a._playbackTimer=setTimeout(function(){a.nextSlide()},a._pauseTime),a.$el.trigger("playback.start",a),a},a.endPlayback=function(){return clearTimeout(a._playbackTimer),a._playbackTimer=!1,a.$el.trigger("playback.end",a),a},a.pausePlayback=function(){return clearTimeout(a._playbackTimer),a._runtime=Math.ceil(new Date-a._runtime),a.$el.trigger("playback.pause",a),a},a.resumePlayback=function(){return a._pauseTime=Math.ceil(a._pauseTime-a._runtime),a._runtime=new Date,a._playbackTimer=setTimeout(function(){a.nextSlide()},a._pauseTime),a.$el.trigger("playback.resume",a),a},a._transition=function(e,i){return a.count<=1?a:0==a.$slides.eq(e).length?a:a._animating?a:(a._animating=!0,a.previous=a.current,a.current=e,"backward"==i?(a.$slides.eq(a.previous).css({display:"block"}),a.$slides.eq(a.current).css({display:"block"}),setTimeout(function(){a.$slides.eq(a.previous).addClass("next-out"),a.$slides.eq(a.current).addClass("prev-in")})):(a.$slides.eq(a.previous).css({display:"block"}),a.$slides.eq(a.current).css({display:"block"}),setTimeout(function(){a.$slides.eq(a.previous).addClass("prev-out"),a.$slides.eq(a.current).addClass("next-in")})),clearTimeout(a._cleanup),a._cleanup=setTimeout(function(){a.$slides.eq(a.current).css({display:"block"}).addClass("active"),a.$slides.eq(a.previous).css({display:"none"}).removeClass("active"),a.$slides.removeClass("next-in next-out prev-in prev-out"),a._animating=!1,a.$el.trigger("transition.after",[a,e,i])},n.transitions.duration),a.$el.trigger("transition.before",[a,e,i]),a)},a.nextSlide=function(){var e=a.current==a.count-1?0:a.current+1;return a._transition(e,"forward"),a.$el.trigger("transition.next",[a,e,"forward"]),a},a.prevSlide=function(){var e=0==a.current?a.count-1:a.current-1;return a._transition(e,"backward"),a.$el.trigger("transition.prev",[a,e,"backward"]),a},a.goToSlide=function(e,i){return this._transition(e,i),a.$el.trigger("transition.to",[a,e,i]),a},a.initialize()},e.EasingSlider.defaults={dimensions:{width:640,height:400,responsive:!0,full_width:!1,image_resizing:!1,keep_ratio:!0,background_images:!1},transitions:{effect:"fade",duration:400},navigation:{arrows:!0,arrows_hover:!1,arrows_position:"inside",pagination:!0,pagination_hover:!1,pagination_position:"inside",pagination_location:"bottom-center"},playback:{enabled:!0,pause:4e3}},e.fn.EasingSlider=function(){return this.each(function(){new e.EasingSlider(this)})},e(document).ready(function(){e(".easingslider").EasingSlider()})}(jQuery);
 
languages/easing-slider.pot DELETED
@@ -1,1103 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: Easing Slider\n"
4
- "POT-Creation-Date: 2015-02-19 17:29-0000\n"
5
- "PO-Revision-Date: 2015-02-19 17:29-0000\n"
6
- "Last-Translator: Matthew Ruddy <support@easingslider.com>\n"
7
- "Language-Team: Easing Slider <support@easingslider.com>\n"
8
- "Language: en_GB\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.6.4\n"
13
- "X-Poedit-Basepath: ../\n"
14
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
- "X-Poedit-KeywordsList: __;_e;_n;_x\n"
16
- "X-Poedit-SearchPath-0: .\n"
17
-
18
- #: backbone/edit-slide.php:10
19
- msgid "Edit Original"
20
- msgstr ""
21
-
22
- #: backbone/edit-slide.php:11
23
- msgid "Replace"
24
- msgstr ""
25
-
26
- #: backbone/edit-slide.php:35
27
- msgid "Link Settings"
28
- msgstr ""
29
-
30
- #: backbone/edit-slide.php:38
31
- msgid "Link To"
32
- msgstr ""
33
-
34
- #: backbone/edit-slide.php:41
35
- msgid "None"
36
- msgstr ""
37
-
38
- #: backbone/edit-slide.php:44
39
- msgid "Custom URL"
40
- msgstr ""
41
-
42
- #: backbone/edit-slide.php:48
43
- msgid "Media File"
44
- msgstr ""
45
-
46
- #: backbone/edit-slide.php:51
47
- msgid "Attachment Page"
48
- msgstr ""
49
-
50
- #: backbone/edit-slide.php:55
51
- msgid "Image URL"
52
- msgstr ""
53
-
54
- #: backbone/edit-slide.php:62
55
- msgid "Open link in a new window/tab"
56
- msgstr ""
57
-
58
- #: backbone/edit-slide.php:76
59
- msgid "Image Settings"
60
- msgstr ""
61
-
62
- #: backbone/edit-slide.php:79
63
- msgid "Title Attribute"
64
- msgstr ""
65
-
66
- #: backbone/edit-slide.php:84
67
- msgid "Alternative Text"
68
- msgstr ""
69
-
70
- #: easing-slider.php:240 includes/class-es-editor-pages.php:62
71
- #: includes/class-es-menu.php:58 includes/class-es-menu.php:59
72
- msgid "Sliders"
73
- msgstr ""
74
-
75
- #: includes/class-es-customizer-notice.php:73
76
- #, php-format
77
- msgid ""
78
- "The Easing Slider \"Customizer\" functionality will soon be removed from "
79
- "this plugin and made available as an extension. If you use the \"Customize\" "
80
- "panel, download and activate the free extension <a href=\"%s\" target="
81
- "\"_blank\">here</a> to prevents any disruptions. <a href=\"%s\">Dismiss</a>."
82
- msgstr ""
83
-
84
- #: includes/class-es-customizer.php:60 includes/class-es-customizer.php:61
85
- msgid "Customize"
86
- msgstr ""
87
-
88
- #: includes/class-es-customizer.php:203
89
- msgid "You need to create some sliders to use the customizer."
90
- msgstr ""
91
-
92
- #: includes/class-es-editor-pages.php:63
93
- msgid "All Sliders"
94
- msgstr ""
95
-
96
- #: includes/class-es-editor-pages.php:88 partials/edit-slider.php:15
97
- msgid "Add New Slider"
98
- msgstr ""
99
-
100
- #: includes/class-es-editor-pages.php:89 partials/edit-slider.php:13
101
- #: partials/list-sliders.php:5
102
- msgid "Add New"
103
- msgstr ""
104
-
105
- #: includes/class-es-editor-pages.php:155
106
- msgid "Are you sure you wish to do this? This cannot be reversed."
107
- msgstr ""
108
-
109
- #: includes/class-es-editor-pages.php:157
110
- msgid "Are you sure you wish to delete this slide? This cannot be reversed."
111
- msgstr ""
112
-
113
- #: includes/class-es-editor-pages.php:158
114
- msgid ""
115
- "Are you sure you wish to delete all of this slider's images? This cannot be "
116
- "reversed."
117
- msgstr ""
118
-
119
- #: includes/class-es-editor-pages.php:160
120
- msgid "Edit Slide"
121
- msgstr ""
122
-
123
- #: includes/class-es-editor-pages.php:161 partials/edit-slider_sidebar.php:41
124
- msgid "Update"
125
- msgstr ""
126
-
127
- #: includes/class-es-editor-pages.php:162
128
- msgid "Image from Media"
129
- msgstr ""
130
-
131
- #: includes/class-es-editor-pages.php:163
132
- msgid "Insert into Slider"
133
- msgstr ""
134
-
135
- #: includes/class-es-editor-pages.php:194
136
- msgid "Sliders per page"
137
- msgstr ""
138
-
139
- #: includes/class-es-editor-pages.php:315
140
- msgid "Slider has been saved successfully."
141
- msgstr ""
142
-
143
- #: includes/class-es-extensions-page.php:64
144
- #: includes/class-es-extensions-page.php:65
145
- msgid "Extensions"
146
- msgstr ""
147
-
148
- #: includes/class-es-image-resizer.php:33
149
- msgid "No image URL has been entered."
150
- msgstr ""
151
-
152
- #: includes/class-es-legacy.php:174
153
- msgid ""
154
- "Looks like you've forgotten to add a slideshow ID to this shortcode. Oh dear!"
155
- msgstr ""
156
-
157
- #: includes/class-es-settings-page.php:58
158
- msgid "Edit Settings"
159
- msgstr ""
160
-
161
- #: includes/class-es-settings-page.php:59
162
- msgid "Settings"
163
- msgstr ""
164
-
165
- #: includes/class-es-settings-page.php:109
166
- msgid "General"
167
- msgstr ""
168
-
169
- #: includes/class-es-settings-page.php:110
170
- msgid "Licenses"
171
- msgstr ""
172
-
173
- #: includes/class-es-settings-page.php:172
174
- msgid "Settings have been saved successfully."
175
- msgstr ""
176
-
177
- #: includes/class-es-shortcode.php:54
178
- msgid "Please select a slider"
179
- msgstr ""
180
-
181
- #: includes/class-es-shortcode.php:68
182
- msgid "Add a slider"
183
- msgstr ""
184
-
185
- #: includes/class-es-shortcode.php:69
186
- msgid "Select a slider to insert from the box below."
187
- msgstr ""
188
-
189
- #: includes/class-es-shortcode.php:74
190
- msgid "Select a slider"
191
- msgstr ""
192
-
193
- #: includes/class-es-shortcode.php:84
194
- msgid "Insert Slider"
195
- msgstr ""
196
-
197
- #: includes/class-es-shortcode.php:85 partials/customizer.php:8
198
- msgid "Close"
199
- msgstr ""
200
-
201
- #: includes/class-es-shortcode.php:115
202
- msgid "Add a Slider"
203
- msgstr ""
204
-
205
- #: includes/class-es-shortcode.php:116
206
- msgid " Add Slider"
207
- msgstr ""
208
-
209
- #: includes/class-es-shortcode.php:148
210
- #, php-format
211
- msgid ""
212
- "<p><strong>The slider specified (ID #%s) could not be found.</strong></p>"
213
- msgstr ""
214
-
215
- #: includes/class-es-slider.php:473
216
- msgid "Slide"
217
- msgstr ""
218
-
219
- #: includes/class-es-slider.php:474
220
- msgid "Fade"
221
- msgstr ""
222
-
223
- #: includes/class-es-slider.php:663
224
- msgid "(no title)"
225
- msgstr ""
226
-
227
- #: includes/class-es-sliders-list-table.php:50
228
- msgid "ID"
229
- msgstr ""
230
-
231
- #: includes/class-es-sliders-list-table.php:51
232
- msgid "Title"
233
- msgstr ""
234
-
235
- #: includes/class-es-sliders-list-table.php:52
236
- msgid "Author"
237
- msgstr ""
238
-
239
- #: includes/class-es-sliders-list-table.php:53
240
- msgid "Date"
241
- msgstr ""
242
-
243
- #: includes/class-es-sliders-list-table.php:54
244
- msgid "Shortcode"
245
- msgstr ""
246
-
247
- #: includes/class-es-sliders-list-table.php:55
248
- msgid "Template Function"
249
- msgstr ""
250
-
251
- #: includes/class-es-sliders-list-table.php:183
252
- msgid "Duplicate"
253
- msgstr ""
254
-
255
- #: includes/class-es-sliders-list-table.php:184
256
- msgid "Delete"
257
- msgstr ""
258
-
259
- #: includes/class-es-sliders-list-table.php:253
260
- #, php-format
261
- msgid "%s - Copy"
262
- msgstr ""
263
-
264
- #: includes/class-es-sliders-list-table.php:354
265
- #, php-format
266
- msgid "%s ago"
267
- msgstr ""
268
-
269
- #: includes/class-es-sliders-list-table.php:360
270
- msgid "Y/m/d"
271
- msgstr ""
272
-
273
- #: includes/class-es-sliders-list-table.php:364
274
- msgid "Published"
275
- msgstr ""
276
-
277
- #: includes/class-es-sliders-list-table.php:420
278
- msgid "No sliders found."
279
- msgstr ""
280
-
281
- #: includes/class-es-update-manager.php:181
282
- msgid ""
283
- "The license key registration service is temporarily unavailable. Please try "
284
- "again later."
285
- msgstr ""
286
-
287
- #: includes/class-es-update-manager.php:239
288
- msgid ""
289
- "Your license could not be deactivated. Please contact support to have it "
290
- "deactivated correctly."
291
- msgstr ""
292
-
293
- #: includes/class-es-update-manager.php:317
294
- #, php-format
295
- msgid "\"%s\" License has been registered successfully."
296
- msgstr ""
297
-
298
- #: includes/class-es-update-manager.php:353
299
- #, php-format
300
- msgid "\"%s\" License has been deactivated successfully."
301
- msgstr ""
302
-
303
- #: includes/class-es-update-manager.php:386
304
- #, php-format
305
- msgid "\"%s\" License Key"
306
- msgstr ""
307
-
308
- #: includes/class-es-update-manager.php:395
309
- msgid "Deactivate"
310
- msgstr ""
311
-
312
- #: includes/class-es-welcome-pages.php:27
313
- #: includes/class-es-welcome-pages.php:28
314
- msgid "Welcome to Easing Slider"
315
- msgstr ""
316
-
317
- #: includes/class-es-welcome-pages.php:36
318
- #: includes/class-es-welcome-pages.php:37
319
- msgid "Getting started with Easing Slider"
320
- msgstr ""
321
-
322
- #: includes/class-es-welcome-pages.php:45
323
- #: includes/class-es-welcome-pages.php:46
324
- msgid "The people that build Easing Slider"
325
- msgstr ""
326
-
327
- #: includes/class-es-welcome-pages.php:111
328
- msgid "What's New"
329
- msgstr ""
330
-
331
- #: includes/class-es-welcome-pages.php:112
332
- msgid "Getting Started"
333
- msgstr ""
334
-
335
- #: includes/class-es-welcome-pages.php:113
336
- msgid "Credits"
337
- msgstr ""
338
-
339
- #: includes/class-es-widget.php:28
340
- msgid "Slider"
341
- msgstr ""
342
-
343
- #: includes/class-es-widget.php:29
344
- msgid "Display a slider using a widget"
345
- msgstr ""
346
-
347
- #: includes/class-es-widget.php:105
348
- msgid "Title:"
349
- msgstr ""
350
-
351
- #: includes/class-es-widget.php:109
352
- msgid "Select Slider:"
353
- msgstr ""
354
-
355
- #: includes/class-es-widget.php:111
356
- msgid "&#8212; Select &#8212;"
357
- msgstr ""
358
-
359
- #: includes/class-es-widget.php:113
360
- #, php-format
361
- msgid " (ID #%s)"
362
- msgstr ""
363
-
364
- #: includes/helpers.php:231
365
- #, php-format
366
- msgid ""
367
- "Please rate <strong>Easing Slider</strong> <a href=\"%1$s\" target=\"_blank"
368
- "\">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href=\"%1$s\" target="
369
- "\"_blank\">WordPress.org</a> to help us keep this plugin free. Thank you "
370
- "from the Easing Slider team!"
371
- msgstr ""
372
-
373
- #: includes/helpers.php:231
374
- msgid "http://wordpress.org/support/view/plugin-reviews/easing-slider?filter=5"
375
- msgstr ""
376
-
377
- #: partials/customizer.php:5
378
- msgid "Save"
379
- msgstr ""
380
-
381
- #: partials/customizer.php:11
382
- msgid "Back"
383
- msgstr ""
384
-
385
- #: partials/customizer.php:18
386
- #, php-format
387
- msgid "You are customizing <strong class=\"theme-name\">%s</strong>"
388
- msgstr ""
389
-
390
- #: partials/customizer.php:20
391
- msgid "Change to another slider"
392
- msgstr ""
393
-
394
- #: partials/customizer.php:32 partials/edit-slider_sidebar.php:216
395
- msgid "Next & Previous Arrows"
396
- msgstr ""
397
-
398
- #: partials/customizer.php:36
399
- msgid "\"Next\" Arrow Image"
400
- msgstr ""
401
-
402
- #: partials/customizer.php:42
403
- msgid "\"Previous\" Arrow Image"
404
- msgstr ""
405
-
406
- #: partials/customizer.php:48 partials/customizer.php:102
407
- msgid "Width"
408
- msgstr ""
409
-
410
- #: partials/customizer.php:54
411
- msgid "Height"
412
- msgstr ""
413
-
414
- #: partials/customizer.php:62 partials/edit-slider_sidebar.php:284
415
- msgid "Pagination Icons"
416
- msgstr ""
417
-
418
- #: partials/customizer.php:66
419
- msgid "\"Inactive\" Image"
420
- msgstr ""
421
-
422
- #: partials/customizer.php:72
423
- msgid "\"Active\" Image"
424
- msgstr ""
425
-
426
- #: partials/customizer.php:78
427
- msgid "Icon Width"
428
- msgstr ""
429
-
430
- #: partials/customizer.php:84
431
- msgid "Icon Height"
432
- msgstr ""
433
-
434
- #: partials/customizer.php:92
435
- msgid "Border"
436
- msgstr ""
437
-
438
- #: partials/customizer.php:96
439
- msgid "Color"
440
- msgstr ""
441
-
442
- #: partials/customizer.php:108
443
- msgid "Radius"
444
- msgstr ""
445
-
446
- #: partials/customizer.php:116
447
- msgid "Drop Shadow"
448
- msgstr ""
449
-
450
- #: partials/customizer.php:120
451
- msgid "Display a Drop Shadow"
452
- msgstr ""
453
-
454
- #: partials/customizer.php:121 partials/edit-slider_sidebar.php:247
455
- #: partials/edit-slider_sidebar.php:315
456
- msgid "True"
457
- msgstr ""
458
-
459
- #: partials/customizer.php:122 partials/edit-slider_sidebar.php:250
460
- #: partials/edit-slider_sidebar.php:318
461
- msgid "False"
462
- msgstr ""
463
-
464
- #: partials/customizer.php:127
465
- msgid "Shadow Image"
466
- msgstr ""
467
-
468
- #: partials/customizer.php:138
469
- msgid "Collapse Sidebar"
470
- msgstr ""
471
-
472
- #: partials/customizer.php:140
473
- msgid "Collapse"
474
- msgstr ""
475
-
476
- #: partials/discover-extensions.php:3
477
- msgid "Extensions for Easing Slider"
478
- msgstr ""
479
-
480
- #: partials/discover-extensions.php:6
481
- msgid "Browse All"
482
- msgstr ""
483
-
484
- #: partials/discover-extensions.php:10
485
- msgid ""
486
- "These extensions enhance Easing Slider, adding new features, providing new "
487
- "slide types and integrating Easing Slider with other plugins."
488
- msgstr ""
489
-
490
- #: partials/discover-extensions.php:20
491
- msgid "Learn More &rarr;"
492
- msgstr ""
493
-
494
- #: partials/discover-extensions.php:24
495
- #, php-format
496
- msgid ""
497
- "There was an error retrieving the extensions list from the server. Please "
498
- "try again later. <a href=\"%s\" target=\"_blank\">Click here</a> to view all "
499
- "extensions on our website."
500
- msgstr ""
501
-
502
- #: partials/edit-settings.php:37
503
- msgid "Save Settings"
504
- msgstr ""
505
-
506
- #: partials/edit-settings_general.php:4
507
- msgid "Asset Loading"
508
- msgstr ""
509
-
510
- #: partials/edit-settings_general.php:8
511
- msgid "Compatibility (header)"
512
- msgstr ""
513
-
514
- #: partials/edit-settings_general.php:13
515
- msgid "Optimized (footer)"
516
- msgstr ""
517
-
518
- #: partials/edit-settings_general.php:16
519
- msgid ""
520
- "This option controls where the plugin's scripts and styling are loaded. "
521
- "\"Compatibility\" will load them in the page header, which is less "
522
- "performant but also less likely to suffer conflicts with other plugins. "
523
- "\"Optimized\" conditionally loads CSS and JS in the page footer, which is "
524
- "better for performance, but more likely to encounter errors. We recommend "
525
- "trying \"Optimized\" and reverting back if you encounter any issues."
526
- msgstr ""
527
-
528
- #: partials/edit-settings_general.php:22
529
- msgid "Data Settings"
530
- msgstr ""
531
-
532
- #: partials/edit-settings_general.php:27
533
- msgid "Remove data on uninstall?"
534
- msgstr ""
535
-
536
- #: partials/edit-settings_general.php:32
537
- msgid ""
538
- "Check this box if you would like Easing Slider to completely remove all of "
539
- "its data when the plugin is deleted."
540
- msgstr ""
541
-
542
- #: partials/edit-settings_general.php:35
543
- msgid ""
544
- "Be careful before enabling this option, as the data cannot be recovered once "
545
- "it has been deleted."
546
- msgstr ""
547
-
548
- #: partials/edit-settings_general.php:41
549
- msgid "Installation Settings"
550
- msgstr ""
551
-
552
- #: partials/edit-settings_general.php:46
553
- msgid "PHP Version"
554
- msgstr ""
555
-
556
- #: partials/edit-settings_general.php:51
557
- msgid "MySQL Version"
558
- msgstr ""
559
-
560
- #: partials/edit-settings_general.php:56
561
- msgid "WordPress Version"
562
- msgstr ""
563
-
564
- #: partials/edit-settings_general.php:61
565
- msgid "Plugin Version"
566
- msgstr ""
567
-
568
- #: partials/edit-settings_licenses.php:1
569
- #, php-format
570
- msgid ""
571
- "Below you can register your extension licenses. This is required to enable "
572
- "extension updates. You can browse all available extensions <a href=\"%s"
573
- "\">here</a>."
574
- msgstr ""
575
-
576
- #: partials/edit-slider.php:12
577
- msgid "Edit Slider"
578
- msgstr ""
579
-
580
- #: partials/edit-slider.php:22
581
- msgid "Name:"
582
- msgstr ""
583
-
584
- #: partials/edit-slider.php:23
585
- msgid "Enter a slider name"
586
- msgstr ""
587
-
588
- #: partials/edit-slider.php:24
589
- msgid "Select All"
590
- msgstr ""
591
-
592
- #: partials/edit-slider.php:30
593
- msgid "Randomize the slide order"
594
- msgstr ""
595
-
596
- #: partials/edit-slider.php:32
597
- msgid "Add Slides"
598
- msgstr ""
599
-
600
- #: partials/edit-slider.php:33
601
- msgid "Bulk Select"
602
- msgstr ""
603
-
604
- #: partials/edit-slider.php:34
605
- msgid "Cancel Selection"
606
- msgstr ""
607
-
608
- #: partials/edit-slider.php:35
609
- msgid "Delete Selected"
610
- msgstr ""
611
-
612
- #: partials/edit-slider_sidebar.php:11
613
- msgid "Publish"
614
- msgstr ""
615
-
616
- #: partials/edit-slider_sidebar.php:24
617
- #, php-format
618
- msgid "Published on: <b>%s</b>"
619
- msgstr ""
620
-
621
- #: partials/edit-slider_sidebar.php:26
622
- msgid "Not published yet."
623
- msgstr ""
624
-
625
- #: partials/edit-slider_sidebar.php:54
626
- msgid ""
627
- "Check out Easing Slider, an easy to use free slider plugin for WordPress."
628
- msgstr ""
629
-
630
- #: partials/edit-slider_sidebar.php:67
631
- #, php-format
632
- msgid ""
633
- "Like Easing Slider? <br><a href=\"%s\">Support us with a Tweet &raquo;</a>"
634
- msgstr ""
635
-
636
- #: partials/edit-slider_sidebar.php:68
637
- #, php-format
638
- msgid ""
639
- "Remove this ad? <br><a href=\"%s\" target=\"_blank\">Purchase a premium add-"
640
- "on &raquo;</a>"
641
- msgstr ""
642
-
643
- #: partials/edit-slider_sidebar.php:77
644
- msgid "Dimensions"
645
- msgstr ""
646
-
647
- #: partials/edit-slider_sidebar.php:90
648
- msgid "Width:"
649
- msgstr ""
650
-
651
- #: partials/edit-slider_sidebar.php:96
652
- msgid "Height:"
653
- msgstr ""
654
-
655
- #: partials/edit-slider_sidebar.php:100
656
- msgid "Slideshow \"width\" and \"height\" values (in pixels)."
657
- msgstr ""
658
-
659
- #: partials/edit-slider_sidebar.php:107
660
- msgid "Make this slider responsive."
661
- msgstr ""
662
-
663
- #: partials/edit-slider_sidebar.php:110
664
- msgid ""
665
- "Check this option to make this slider responsive. If enabled, the \"width\" "
666
- "and \"height\" values above will act as maximums."
667
- msgstr ""
668
-
669
- #: partials/edit-slider_sidebar.php:114
670
- msgid "Advanced Options"
671
- msgstr ""
672
-
673
- #: partials/edit-slider_sidebar.php:120
674
- #, php-format
675
- msgid "Enable 100% full width."
676
- msgstr ""
677
-
678
- #: partials/edit-slider_sidebar.php:123
679
- msgid ""
680
- "When enabled, the slider will set its container width to 100%. This option "
681
- "works for responsive sliders only. For best results, it's recommend that you "
682
- "disable image resizing when this option is enabled."
683
- msgstr ""
684
-
685
- #: partials/edit-slider_sidebar.php:129
686
- msgid "Crop & resize images to fit slider."
687
- msgstr ""
688
-
689
- #: partials/edit-slider_sidebar.php:132
690
- msgid ""
691
- "Tick this option to have the slider crop & resize images to fit the slider "
692
- "dimensions. This will only work with images from the WordPress Media Library."
693
- msgstr ""
694
-
695
- #: partials/edit-slider_sidebar.php:138
696
- msgid "Proportionally resize slider."
697
- msgstr ""
698
-
699
- #: partials/edit-slider_sidebar.php:141
700
- msgid ""
701
- "This option enables proportional slider resizing for responsive sliders. "
702
- "This maintains the aspect ratio. Disable this option for fixed height "
703
- "sliders."
704
- msgstr ""
705
-
706
- #: partials/edit-slider_sidebar.php:147
707
- msgid "Use background images."
708
- msgstr ""
709
-
710
- #: partials/edit-slider_sidebar.php:150
711
- msgid ""
712
- "Enable this option if you want the slider to use CSS background images for "
713
- "image slides."
714
- msgstr ""
715
-
716
- #: partials/edit-slider_sidebar.php:168
717
- msgid "Transitions"
718
- msgstr ""
719
-
720
- #: partials/edit-slider_sidebar.php:181
721
- msgid "Effect:"
722
- msgstr ""
723
-
724
- #: partials/edit-slider_sidebar.php:189
725
- msgid "Choose the transition effect you would like to use."
726
- msgstr ""
727
-
728
- #: partials/edit-slider_sidebar.php:196
729
- msgid "Duration:"
730
- msgstr ""
731
-
732
- #: partials/edit-slider_sidebar.php:200
733
- msgid "Sets the duration (in milliseconds) for the slideshow transition."
734
- msgstr ""
735
-
736
- #: partials/edit-slider_sidebar.php:228
737
- msgid "Arrows:"
738
- msgstr ""
739
-
740
- #: partials/edit-slider_sidebar.php:231 partials/edit-slider_sidebar.php:299
741
- #: partials/edit-slider_sidebar.php:375
742
- msgid "Enable"
743
- msgstr ""
744
-
745
- #: partials/edit-slider_sidebar.php:234 partials/edit-slider_sidebar.php:302
746
- #: partials/edit-slider_sidebar.php:378
747
- msgid "Disable"
748
- msgstr ""
749
-
750
- #: partials/edit-slider_sidebar.php:238
751
- msgid "Toggles the next and previous slide arrows."
752
- msgstr ""
753
-
754
- #: partials/edit-slider_sidebar.php:244 partials/edit-slider_sidebar.php:312
755
- msgid "On Hover:"
756
- msgstr ""
757
-
758
- #: partials/edit-slider_sidebar.php:254
759
- msgid ""
760
- "Set to \"True\" to only show the arrows when the user hovers over the "
761
- "slideshow."
762
- msgstr ""
763
-
764
- #: partials/edit-slider_sidebar.php:261 partials/edit-slider_sidebar.php:329
765
- msgid "Position:"
766
- msgstr ""
767
-
768
- #: partials/edit-slider_sidebar.php:263 partials/edit-slider_sidebar.php:331
769
- msgid "Inside"
770
- msgstr ""
771
-
772
- #: partials/edit-slider_sidebar.php:264 partials/edit-slider_sidebar.php:332
773
- msgid "Outside"
774
- msgstr ""
775
-
776
- #: partials/edit-slider_sidebar.php:268
777
- msgid "Select a position for the arrows."
778
- msgstr ""
779
-
780
- #: partials/edit-slider_sidebar.php:296
781
- msgid "Pagination:"
782
- msgstr ""
783
-
784
- #: partials/edit-slider_sidebar.php:306
785
- msgid ""
786
- "Enable/Disable the Pagination Icons. Each icon represents a slide in their "
787
- "respective order."
788
- msgstr ""
789
-
790
- #: partials/edit-slider_sidebar.php:322
791
- msgid ""
792
- "Set to \"True\" to only show the pagination when the user hovers over the "
793
- "slideshow."
794
- msgstr ""
795
-
796
- #: partials/edit-slider_sidebar.php:335
797
- msgid "Top Left"
798
- msgstr ""
799
-
800
- #: partials/edit-slider_sidebar.php:336
801
- msgid "Top Right"
802
- msgstr ""
803
-
804
- #: partials/edit-slider_sidebar.php:337
805
- msgid "Top Center"
806
- msgstr ""
807
-
808
- #: partials/edit-slider_sidebar.php:338
809
- msgid "Bottom Left"
810
- msgstr ""
811
-
812
- #: partials/edit-slider_sidebar.php:339
813
- msgid "Bottom Right"
814
- msgstr ""
815
-
816
- #: partials/edit-slider_sidebar.php:340
817
- msgid "Bottom Center"
818
- msgstr ""
819
-
820
- #: partials/edit-slider_sidebar.php:344
821
- msgid "Select a position for the pagination icons."
822
- msgstr ""
823
-
824
- #: partials/edit-slider_sidebar.php:360
825
- msgid "Automatic Playback"
826
- msgstr ""
827
-
828
- #: partials/edit-slider_sidebar.php:372
829
- msgid "Playback:"
830
- msgstr ""
831
-
832
- #: partials/edit-slider_sidebar.php:382
833
- msgid "Enable/Disable slideshow automatic playback."
834
- msgstr ""
835
-
836
- #: partials/edit-slider_sidebar.php:389
837
- msgid "Pause Duration:"
838
- msgstr ""
839
-
840
- #: partials/edit-slider_sidebar.php:393
841
- msgid ""
842
- "Sets the duration (in milliseconds) for the pause between slide transitions."
843
- msgstr ""
844
-
845
- #: partials/list-sliders.php:3
846
- msgid "Sliders "
847
- msgstr ""
848
-
849
- #: partials/list-sliders.php:9
850
- #, php-format
851
- msgid "Search results for &#8220;%s&#8221;"
852
- msgstr ""
853
-
854
- #: partials/list-sliders.php:27
855
- msgid "Search Sliders"
856
- msgstr ""
857
-
858
- #: partials/welcome.php:2
859
- #, php-format
860
- msgid "Welcome to Easing Slider %s"
861
- msgstr ""
862
-
863
- #: partials/welcome.php:3
864
- #, php-format
865
- msgid ""
866
- "Thank you for updating to the latest version! Easing Slider %s is ready to "
867
- "help you create beautiful sliders easily, quickly and for free!"
868
- msgstr ""
869
-
870
- #: partials/welcome.php:4
871
- #, php-format
872
- msgid "Version %s"
873
- msgstr ""
874
-
875
- #: partials/welcome_about.php:2
876
- msgid "Check out the awesome all new Easing Slider"
877
- msgstr ""
878
-
879
- #: partials/welcome_about.php:3
880
- #, php-format
881
- msgid ""
882
- "We've completely rebuilt Easing Slider from the ground up to be a more "
883
- "stable, modern, easy to use solution for creating sliders on your WordPress "
884
- "blog. There's loads of new features, some of which described below. For more "
885
- "information on the changes, <a href=\"%s\" target=\"_blank\">click here</a>."
886
- msgstr ""
887
-
888
- #: partials/welcome_about.php:9
889
- msgid "List Screenshot"
890
- msgstr ""
891
-
892
- #: partials/welcome_about.php:10
893
- msgid "Unlimited Sliders"
894
- msgstr ""
895
-
896
- #: partials/welcome_about.php:11
897
- msgid ""
898
- "Create as many sliders as you like, Easing Slider is no longer limited to "
899
- "just one slider. We're now using our own custom post type, a significant "
900
- "improvement for developers."
901
- msgstr ""
902
-
903
- #: partials/welcome_about.php:15
904
- msgid "Interface Screenshot"
905
- msgstr ""
906
-
907
- #: partials/welcome_about.php:16
908
- msgid "Simple Interface"
909
- msgstr ""
910
-
911
- #: partials/welcome_about.php:17
912
- msgid ""
913
- "The admin interface has been completely revamped to be easier, yet more "
914
- "powerful. The new look admin is instantly familiar, similar in style to the "
915
- "new WordPress Media Library."
916
- msgstr ""
917
-
918
- #: partials/welcome_about.php:24
919
- msgid "Introducing Extensions"
920
- msgstr ""
921
-
922
- #: partials/welcome_about.php:25
923
- msgid ""
924
- "A vast selection of extensions will soon be available, extending the "
925
- "functionality of Easing Slider beyond what's ever been possible before. View "
926
- "them <a href=\"admin.php?page=easingslider_discover_extensions\">here</a>."
927
- msgstr ""
928
-
929
- #: partials/welcome_about.php:29
930
- msgid "CSS3 Animations"
931
- msgstr ""
932
-
933
- #: partials/welcome_about.php:30
934
- msgid ""
935
- "The plugin now relies entirely on modern CSS3 animations. This ensures "
936
- "smooth transitions, with graceful fallbacks for older browsers."
937
- msgstr ""
938
-
939
- #: partials/welcome_about.php:34
940
- msgid "Developer Friendly"
941
- msgstr ""
942
-
943
- #: partials/welcome_about.php:35
944
- msgid ""
945
- "Our entirely new infrastructure provides developers with more power than "
946
- "ever. More actions, filters, and extensions bring unlimited potential."
947
- msgstr ""
948
-
949
- #: partials/welcome_about.php:41
950
- msgid "More to come"
951
- msgstr ""
952
-
953
- #: partials/welcome_about.php:42
954
- msgid ""
955
- "This update is just the beginning - the future will bring even more "
956
- "improvements to Easing Slider. We have plans for dozens of extensions "
957
- "that'll extend functionality far beyond what was capable before, ensuring "
958
- "Easing Slider remains the best slider plugin for WordPress."
959
- msgstr ""
960
-
961
- #: partials/welcome_about.php:46
962
- msgid "Return to Easing Slider"
963
- msgstr ""
964
-
965
- #: partials/welcome_credits.php:2
966
- msgid "Want to contribute to Easing Slider? Here's how you can."
967
- msgstr ""
968
-
969
- #: partials/welcome_credits.php:6
970
- #, php-format
971
- msgid ""
972
- "Until now, Easing Slider has been developed solely by <a href=\"%s\" target="
973
- "\"_blank\">me</a>, Matthew Ruddy, but it's time for this to change."
974
- msgstr ""
975
-
976
- #: partials/welcome_credits.php:8
977
- #, php-format
978
- msgid ""
979
- "Now, Easing Slider's official channel of development will be managed through "
980
- "<a href=\"%s\" target=\"_blank\">Github</a>, where I hope to encourage "
981
- "involvement from other developers who have a vision for Easing Slider as "
982
- "strong as my own."
983
- msgstr ""
984
-
985
- #: partials/welcome_credits.php:10
986
- #, php-format
987
- msgid ""
988
- "Whether you've encountered a simple bug and want to provide a fix, or you "
989
- "wish to tackle some enhancements or new features, please don't hesitate to "
990
- "<a href=\"%s\" target=\"_blank\">get involved</a>. Even if you can't code, "
991
- "your feedback is greated appreciated and really important to us, so <a href="
992
- "\"%s\" target=\"_blank\">get in touch</a>."
993
- msgstr ""
994
-
995
- #: partials/welcome_credits.php:12
996
- #, php-format
997
- msgid ""
998
- "Hopefully soon this page will be vividly decorated with contributors %s."
999
- msgstr ""
1000
-
1001
- #: partials/welcome_credits.php:15
1002
- msgid "Proudly Built By:"
1003
- msgstr ""
1004
-
1005
- #: partials/welcome_credits.php:19 partials/welcome_credits.php:20
1006
- msgid "Matthew Ruddy"
1007
- msgstr ""
1008
-
1009
- #: partials/welcome_credits.php:21
1010
- msgid "Just an average guy"
1011
- msgstr ""
1012
-
1013
- #: partials/welcome_credits.php:26
1014
- msgid "Contribute on Github"
1015
- msgstr ""
1016
-
1017
- #: partials/welcome_credits.php:27
1018
- msgid "Contact Us"
1019
- msgstr ""
1020
-
1021
- #: partials/welcome_getting-started.php:2
1022
- msgid ""
1023
- "Use the tips below to get started using Easing Slider. It's super quick and "
1024
- "easy!"
1025
- msgstr ""
1026
-
1027
- #: partials/welcome_getting-started.php:8
1028
- msgid "Creating Your First Slider"
1029
- msgstr ""
1030
-
1031
- #: partials/welcome_getting-started.php:10
1032
- msgid "Sliders &rarr; Add New"
1033
- msgstr ""
1034
-
1035
- #: partials/welcome_getting-started.php:11
1036
- msgid ""
1037
- "The \"Sliders\" menu is your access point for all aspects of Easing Slider. "
1038
- "Simply click \"Add New\" to create your first slider and start adding slides."
1039
- msgstr ""
1040
-
1041
- #: partials/welcome_getting-started.php:13
1042
- msgid "Adding Slides"
1043
- msgstr ""
1044
-
1045
- #: partials/welcome_getting-started.php:14
1046
- #, php-format
1047
- msgid ""
1048
- "Click the \"Add Slides\" button to add image slides from the WordPress Media "
1049
- "Library. Other slide types can be purchased from our vast array of "
1050
- "extensions <a href=\"%s\">found here</a>."
1051
- msgstr ""
1052
-
1053
- #: partials/welcome_getting-started.php:18
1054
- msgid "Welcome Screenshot"
1055
- msgstr ""
1056
-
1057
- #: partials/welcome_getting-started.php:25
1058
- msgid "Displaying A Slider"
1059
- msgstr ""
1060
-
1061
- #: partials/welcome_getting-started.php:29
1062
- msgid "Shortcode Screenshot"
1063
- msgstr ""
1064
-
1065
- #: partials/welcome_getting-started.php:30
1066
- msgid "In a post"
1067
- msgstr ""
1068
-
1069
- #: partials/welcome_getting-started.php:36
1070
- msgid "PHP Function Screenshot"
1071
- msgstr ""
1072
-
1073
- #: partials/welcome_getting-started.php:42
1074
- msgid "Widget Screenshot"
1075
- msgstr ""
1076
-
1077
- #: partials/welcome_getting-started.php:51
1078
- msgid "Need help?"
1079
- msgstr ""
1080
-
1081
- #: partials/welcome_getting-started.php:55
1082
- msgid "Helpful Documentation"
1083
- msgstr ""
1084
-
1085
- #: partials/welcome_getting-started.php:56
1086
- #, php-format
1087
- msgid ""
1088
- "We have documentation available covering everything from <a href=\"%s"
1089
- "\">Getting Started</a> to our <a href=\"%s\">Developer API</a>. New "
1090
- "documents and tutorials are added daily."
1091
- msgstr ""
1092
-
1093
- #: partials/welcome_getting-started.php:60
1094
- msgid "Awesome Support"
1095
- msgstr ""
1096
-
1097
- #: partials/welcome_getting-started.php:61
1098
- #, php-format
1099
- msgid ""
1100
- "We work hard to ensure every user gets the best support possible. If you've "
1101
- "encountered a problem or have a question, don't hesitate to <a href=\"%s"
1102
- "\">contact us</a>."
1103
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/easingslider.pot ADDED
@@ -0,0 +1,491 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2016 Matthew Ruddy
2
+ # This file is distributed under the GPL2.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Easing Slider 3.0.0\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/easing-slider\n"
7
+ "POT-Creation-Date: 2016-06-03 12:02:22+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=utf-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2016-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+ "X-Generator: grunt-wp-i18n 0.5.4\n"
15
+
16
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:37
17
+ msgid "Failed to connect to API. No response provided. Please contact support."
18
+ msgstr ""
19
+
20
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:66
21
+ msgid "License has been activated successfully."
22
+ msgstr ""
23
+
24
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:70
25
+ msgid "License has been deactivated successfully."
26
+ msgstr ""
27
+
28
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:87
29
+ msgid "Your license key has expired on %s. Please renew your license key."
30
+ msgstr ""
31
+
32
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:91
33
+ msgid "An invalid item ID has been provided. Please contact support."
34
+ msgstr ""
35
+
36
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:95
37
+ msgid "The license key entered is not a valid license key for this plugin."
38
+ msgstr ""
39
+
40
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:99
41
+ msgid ""
42
+ "The license key provided is a \"bundle\" license key. Bundle license keys "
43
+ "cannot be activated."
44
+ msgstr ""
45
+
46
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:103
47
+ msgid "The license key you have entered does not exist."
48
+ msgstr ""
49
+
50
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:107
51
+ msgid ""
52
+ "Your license key has reached its activation limit of %d. Please upgrade "
53
+ "your license key to get more activations."
54
+ msgstr ""
55
+
56
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:111
57
+ msgid "Your license key has been revoked. Please contact support."
58
+ msgstr ""
59
+
60
+ #: src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php:115
61
+ msgid "An unknown error occurred. Please contact support."
62
+ msgstr ""
63
+
64
+ #: src/Foundation/Admin/Panels/SettingsApiPanel.php:166
65
+ msgid "Settings updated."
66
+ msgstr ""
67
+
68
+ #: src/Foundation/Admin/Panels/SettingsApiPanel.php:258
69
+ #: src/Foundation/Admin/Panels/SettingsApiPanel.php:283
70
+ #: src/Foundation/Admin/Panels/SettingsApiPanel.php:383
71
+ msgid "No options available."
72
+ msgstr ""
73
+
74
+ #: src/Foundation/Admin/Panels/SettingsApiPanel.php:362
75
+ msgid "The callback function used for the <strong>%s</strong> setting is missing."
76
+ msgstr ""
77
+
78
+ #: src/Plugin/Activation/Activator.php:57
79
+ msgid ""
80
+ "Sorry, but your version of PHP (v%s) is not supported. PHP v5.3.0 or "
81
+ "greater is required. The plugin has been deactivated. <a href=\"%s\">Return "
82
+ "to the Dashboard.</a>"
83
+ msgstr ""
84
+
85
+ #: src/Plugin/Activation/Activator.php:64
86
+ msgid ""
87
+ "Sorry, but your version of WordPress, <strong>%s</strong>, is not "
88
+ "supported. The plugin has been deactivated. <a href=\"%s\">Return to the "
89
+ "Dashboard.</a>"
90
+ msgstr ""
91
+
92
+ #: src/Plugin/Admin/Actions/Addons.php:102
93
+ msgid "Please enter a license key."
94
+ msgstr ""
95
+
96
+ #: src/Plugin/Admin/Actions/Sliders.php:49
97
+ msgid "Slider has been published successfully."
98
+ msgstr ""
99
+
100
+ #: src/Plugin/Admin/Actions/Sliders.php:50
101
+ msgid "Slider has been saved successfully."
102
+ msgstr ""
103
+
104
+ #: src/Plugin/Admin/Actions/Sliders.php:51
105
+ msgid "Slider(s) duplicated successfully"
106
+ msgstr ""
107
+
108
+ #: src/Plugin/Admin/Actions/Sliders.php:52
109
+ msgid "Slider(s) moved to the Trash."
110
+ msgstr ""
111
+
112
+ #: src/Plugin/Admin/Actions/Sliders.php:53
113
+ msgid "Slider(s) restored successfully."
114
+ msgstr ""
115
+
116
+ #: src/Plugin/Admin/Actions/Sliders.php:54
117
+ msgid "Slider(s) deleted permanently."
118
+ msgstr ""
119
+
120
+ #: src/Plugin/Admin/Assets/Assets.php:71
121
+ msgid "Are you sure you wish to do this? This cannot be reversed."
122
+ msgstr ""
123
+
124
+ #: src/Plugin/Admin/Assets/Assets.php:75
125
+ msgid "Are you sure you wish to delete this slide? This cannot be reversed."
126
+ msgstr ""
127
+
128
+ #: src/Plugin/Admin/Assets/Assets.php:76
129
+ msgid ""
130
+ "Are you sure you wish to delete all of this slider's images? This cannot be "
131
+ "reversed."
132
+ msgstr ""
133
+
134
+ #: src/Plugin/Admin/Assets/Assets.php:78
135
+ msgid "Edit Slide"
136
+ msgstr ""
137
+
138
+ #: src/Plugin/Admin/Assets/Assets.php:79
139
+ msgid "Back"
140
+ msgstr ""
141
+
142
+ #: src/Plugin/Admin/Assets/Assets.php:80
143
+ msgid "Update"
144
+ msgstr ""
145
+
146
+ #: src/Plugin/Admin/Assets/Assets.php:81
147
+ msgid "Replace"
148
+ msgstr ""
149
+
150
+ #: src/Plugin/Admin/Assets/Assets.php:82
151
+ msgid "Replace Image"
152
+ msgstr ""
153
+
154
+ #: src/Plugin/Admin/Assets/Assets.php:83
155
+ msgid "Image from Media"
156
+ msgstr ""
157
+
158
+ #: src/Plugin/Admin/Assets/Assets.php:84
159
+ msgid "Insert into Slider"
160
+ msgstr ""
161
+
162
+ #: src/Plugin/Admin/Assets/Assets.php:87
163
+ msgid "Activate Addon"
164
+ msgstr ""
165
+
166
+ #: src/Plugin/Admin/Assets/Assets.php:88
167
+ msgid "Deactivate Addon"
168
+ msgstr ""
169
+
170
+ #: src/Plugin/Admin/Assets/Assets.php:89
171
+ msgid "Activating..."
172
+ msgstr ""
173
+
174
+ #: src/Plugin/Admin/Assets/Assets.php:90
175
+ msgid "Deactivating..."
176
+ msgstr ""
177
+
178
+ #: src/Plugin/Admin/Assets/Assets.php:91
179
+ msgid "Installing..."
180
+ msgstr ""
181
+
182
+ #: src/Plugin/Admin/Assets/Assets.php:94
183
+ msgid "Status: Active"
184
+ msgstr ""
185
+
186
+ #: src/Plugin/Admin/Assets/Assets.php:95
187
+ msgid "Status: Inactive"
188
+ msgstr ""
189
+
190
+ #: src/Plugin/Admin/ListTables/Sliders.php:115
191
+ msgid "All"
192
+ msgstr ""
193
+
194
+ #: src/Plugin/Admin/ListTables/Sliders.php:116
195
+ #: src/Plugin/Admin/ListTables/Sliders.php:473
196
+ msgid "Published"
197
+ msgstr ""
198
+
199
+ #: src/Plugin/Admin/ListTables/Sliders.php:121
200
+ msgid "Trashed"
201
+ msgstr ""
202
+
203
+ #: src/Plugin/Admin/ListTables/Sliders.php:138
204
+ msgid "ID"
205
+ msgstr ""
206
+
207
+ #: src/Plugin/Admin/ListTables/Sliders.php:139
208
+ msgid "Title"
209
+ msgstr ""
210
+
211
+ #: src/Plugin/Admin/ListTables/Sliders.php:140
212
+ msgid "Author"
213
+ msgstr ""
214
+
215
+ #: src/Plugin/Admin/ListTables/Sliders.php:141
216
+ msgid "Date"
217
+ msgstr ""
218
+
219
+ #: src/Plugin/Admin/ListTables/Sliders.php:142
220
+ msgid "Shortcode"
221
+ msgstr ""
222
+
223
+ #: src/Plugin/Admin/ListTables/Sliders.php:143
224
+ msgid "Template Function"
225
+ msgstr ""
226
+
227
+ #: src/Plugin/Admin/ListTables/Sliders.php:279
228
+ msgid "Restore"
229
+ msgstr ""
230
+
231
+ #: src/Plugin/Admin/ListTables/Sliders.php:280
232
+ msgid "Delete Permanently"
233
+ msgstr ""
234
+
235
+ #: src/Plugin/Admin/ListTables/Sliders.php:283
236
+ msgid "Duplicate"
237
+ msgstr ""
238
+
239
+ #: src/Plugin/Admin/ListTables/Sliders.php:284
240
+ msgid "Move to Trash"
241
+ msgstr ""
242
+
243
+ #: src/Plugin/Admin/ListTables/Sliders.php:463
244
+ msgid "%s ago"
245
+ msgstr ""
246
+
247
+ #: src/Plugin/Admin/ListTables/Sliders.php:469
248
+ msgid "Y/m/d"
249
+ msgstr ""
250
+
251
+ #: src/Plugin/Admin/ListTables/Sliders.php:529
252
+ msgid "No sliders found."
253
+ msgstr ""
254
+
255
+ #: src/Plugin/Admin/MediaButton.php:78
256
+ msgid "Add a Slider"
257
+ msgstr ""
258
+
259
+ #: src/Plugin/Admin/MediaButton.php:79
260
+ msgid " Add Slider"
261
+ msgstr ""
262
+
263
+ #: src/Plugin/Admin/MediaButton.php:112
264
+ msgid "Please select a slider"
265
+ msgstr ""
266
+
267
+ #: src/Plugin/Admin/MediaButton.php:126
268
+ msgid "Add a slider"
269
+ msgstr ""
270
+
271
+ #: src/Plugin/Admin/MediaButton.php:127
272
+ msgid "Select a slider to insert from the box below."
273
+ msgstr ""
274
+
275
+ #: src/Plugin/Admin/MediaButton.php:132
276
+ msgid "Select a slider"
277
+ msgstr ""
278
+
279
+ #: src/Plugin/Admin/MediaButton.php:140
280
+ msgid "Insert Slider"
281
+ msgstr ""
282
+
283
+ #: src/Plugin/Admin/MediaButton.php:141
284
+ msgid "Close"
285
+ msgstr ""
286
+
287
+ #: src/Plugin/Admin/Menus/Menu.php:59 src/Plugin/Admin/Menus/Menu.php:60
288
+ #: src/Plugin/Admin/Menus/Menu.php:76 src/Plugin/Repositories/Sliders.php:38
289
+ msgid "Sliders"
290
+ msgstr ""
291
+
292
+ #: src/Plugin/Admin/Menus/Menu.php:77
293
+ msgid "All Sliders"
294
+ msgstr ""
295
+
296
+ #: src/Plugin/Admin/Menus/Menu.php:92
297
+ msgid "Add New Slider"
298
+ msgstr ""
299
+
300
+ #: src/Plugin/Admin/Menus/Menu.php:93
301
+ msgid "Add New"
302
+ msgstr ""
303
+
304
+ #: src/Plugin/Admin/Menus/Menu.php:108 src/Plugin/Admin/Menus/Menu.php:109
305
+ msgid "Settings"
306
+ msgstr ""
307
+
308
+ #: src/Plugin/Admin/Menus/Menu.php:124
309
+ msgid "Addons"
310
+ msgstr ""
311
+
312
+ #: src/Plugin/Admin/Menus/Menu.php:125
313
+ msgid "Get More Features!"
314
+ msgstr ""
315
+
316
+ #: src/Plugin/Admin/Panels/EditSlider.php:62
317
+ msgid "Slide"
318
+ msgstr ""
319
+
320
+ #: src/Plugin/Admin/Panels/EditSlider.php:63
321
+ msgid "Fade"
322
+ msgstr ""
323
+
324
+ #: src/Plugin/Admin/Panels/EditSlider.php:75
325
+ msgid "Media"
326
+ msgstr ""
327
+
328
+ #: src/Plugin/Admin/Panels/Panels.php:39
329
+ msgid ""
330
+ "Please rate <strong>Easing Slider</strong> <a href=\"%1$s\" "
331
+ "target=\"_blank\">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a "
332
+ "href=\"%1$s\" target=\"_blank\">WordPress.org</a> to help us keep this "
333
+ "plugin free. Thank you from the Easing Slider team!"
334
+ msgstr ""
335
+
336
+ #: src/Plugin/Admin/Panels/Panels.php:40
337
+ msgid "http://wordpress.org/support/view/plugin-reviews/easing-slider?filter=5"
338
+ msgstr ""
339
+
340
+ #: src/Plugin/Admin/Panels/Settings.php:37
341
+ msgid "General"
342
+ msgstr ""
343
+
344
+ #: src/Plugin/Admin/Panels/Settings.php:38
345
+ msgid "Diagnostics"
346
+ msgstr ""
347
+
348
+ #: src/Plugin/Admin/Panels/Settings.php:54
349
+ msgid "Asset Loading"
350
+ msgstr ""
351
+
352
+ #: src/Plugin/Admin/Panels/Settings.php:58
353
+ msgid "Load in Footer"
354
+ msgstr ""
355
+
356
+ #: src/Plugin/Admin/Panels/Settings.php:60
357
+ msgid ""
358
+ "Should Easing Slider load it's CSS & Javascript in the page footer? This "
359
+ "reduces page loading time, but may be prone to conflicts with other plugins."
360
+ msgstr ""
361
+
362
+ #: src/Plugin/Admin/Panels/Settings.php:64
363
+ msgid "Data Settings"
364
+ msgstr ""
365
+
366
+ #: src/Plugin/Admin/Panels/Settings.php:68
367
+ msgid "Remove data on uninstall?"
368
+ msgstr ""
369
+
370
+ #: src/Plugin/Admin/Panels/Settings.php:70
371
+ msgid ""
372
+ "Check this box if you would like Easing Slider to completely remove all of "
373
+ "its data when the plugin is deleted."
374
+ msgstr ""
375
+
376
+ #: src/Plugin/Admin/Panels/Settings.php:74
377
+ msgid "Reset data to defaults"
378
+ msgstr ""
379
+
380
+ #: src/Plugin/Admin/Panels/Settings.php:77
381
+ msgid "Reset Plugin"
382
+ msgstr ""
383
+
384
+ #: src/Plugin/Admin/Panels/Settings.php:78
385
+ msgid ""
386
+ "Click this button to completely reset your Easing Slider settings back to "
387
+ "defaults. Be careful, as this process cannot be reversed!"
388
+ msgstr ""
389
+
390
+ #: src/Plugin/Admin/Panels/Settings.php:83
391
+ msgid "System Settings"
392
+ msgstr ""
393
+
394
+ #: src/Plugin/Admin/Panels/Settings.php:87
395
+ msgid "PHP Version"
396
+ msgstr ""
397
+
398
+ #: src/Plugin/Admin/Panels/Settings.php:92
399
+ msgid "MySQL Version"
400
+ msgstr ""
401
+
402
+ #: src/Plugin/Admin/Panels/Settings.php:97
403
+ msgid "WordPress Version"
404
+ msgstr ""
405
+
406
+ #: src/Plugin/Admin/Panels/Settings.php:102
407
+ msgid "Plugin Version"
408
+ msgstr ""
409
+
410
+ #: src/Plugin/Admin/UpgraderSkin.php:85
411
+ msgid "There was an error installing the addon. Please try again."
412
+ msgstr ""
413
+
414
+ #: src/Plugin/Shortcodes/Slider.php:82
415
+ msgid "<p><strong>The slider specified (ID #%d) could not be found.</strong></p>"
416
+ msgstr ""
417
+
418
+ #: src/Plugin/Views/Slider.php:48
419
+ msgid ""
420
+ "<p><strong>The slider ID #%d has no slides. Cannot display the "
421
+ "slider.</strong></p>"
422
+ msgstr ""
423
+
424
+ #: src/Plugin/Widgets/Slider.php:59
425
+ msgid "Slider"
426
+ msgstr ""
427
+
428
+ #: src/Plugin/Widgets/Slider.php:69
429
+ msgid "Display a slider using a widget."
430
+ msgstr ""
431
+
432
+ #: src/Plugin/Widgets/Slider.php:100
433
+ msgid "Title:"
434
+ msgstr ""
435
+
436
+ #: src/Plugin/Widgets/Slider.php:104
437
+ msgid "Select Slider:"
438
+ msgstr ""
439
+
440
+ #: src/Plugin/Widgets/Slider.php:106
441
+ msgid "&#8212; Select &#8212;"
442
+ msgstr ""
443
+
444
+ #: src/Plugin/Widgets/Slider.php:108
445
+ msgid " (ID #%s)"
446
+ msgstr ""
447
+
448
+ #: src/Plugin/helpers.php:461
449
+ msgid ""
450
+ "An upgrade to your license key is required to allow addon access when using "
451
+ "Easing Slider v3.0.0 or greater. <a href=\"%s\" target=\"_blank\">Click "
452
+ "here</a> to get your new license key for free."
453
+ msgstr ""
454
+
455
+ #: src/Plugin/helpers.php:502
456
+ msgid "Thanks for Upgrading!"
457
+ msgstr ""
458
+
459
+ #: src/Plugin/helpers.php:503
460
+ msgid ""
461
+ "Thank you for upgrading to Easing Slider v3! So much has changed - please "
462
+ "check out the important update information below."
463
+ msgstr ""
464
+
465
+ #: src/Plugin/helpers.php:507
466
+ msgid "Important Addon & Licensing Changes"
467
+ msgstr ""
468
+
469
+ #: src/Plugin/helpers.php:511
470
+ msgid "Dismiss"
471
+ msgstr ""
472
+
473
+ #. Plugin Name of the plugin/theme
474
+ msgid "Easing Slider"
475
+ msgstr ""
476
+
477
+ #. Plugin URI of the plugin/theme
478
+ msgid "http://easingslider.com/"
479
+ msgstr ""
480
+
481
+ #. Description of the plugin/theme
482
+ msgid "A simple WordPress plugin for creating beautiful sliders."
483
+ msgstr ""
484
+
485
+ #. Author of the plugin/theme
486
+ msgid "Matthew Ruddy"
487
+ msgstr ""
488
+
489
+ #. Author URI of the plugin/theme
490
+ msgid "http://matthewruddy.com"
491
+ msgstr ""
package.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "easing-slider",
3
+ "title": "Easing Slider",
4
+ "version": "3.0.0",
5
+ "devDependencies": {
6
+ "grunt": "0.4.5",
7
+ "grunt-contrib-concat": "^0.5.1",
8
+ "grunt-contrib-copy": "^0.8.1",
9
+ "grunt-contrib-cssmin": "0.12.*",
10
+ "grunt-contrib-uglify": "0.9.*",
11
+ "grunt-contrib-watch": "0.6.*",
12
+ "grunt-replace": "^0.11.0",
13
+ "grunt-wp-i18n": "^0.5.4"
14
+ }
15
+ }
partials/customizer.php DELETED
@@ -1,161 +0,0 @@
1
- <div id="customize-container" class="customize-container">
2
- <div class="wp-full-overlay expanded">
3
- <form id="customize-controls" action="admin.php?page=<?php echo esc_attr( $page ); if ( isset( $id ) ) { echo "&amp;edit=". esc_attr( $id ) .""; } ?>" method="post" class="wrap wp-full-overlay-sidebar">
4
- <div id="customize-header-actions" class="wp-full-overlay-header">
5
- <input type="submit" name="save" id="save" class="button button-primary save" value="<?php _e( 'Save', 'easingslider' ); ?>" />
6
- <span class="spinner"></span>
7
- <a class="customize-controls-close" href="admin.php?page=easingslider_edit_sliders">
8
- <span class="screen-reader-text"><?php _e( 'Close', 'easingslider' ); ?></span>
9
- </a>
10
- <span class="control-panel-back" tabindex="-1">
11
- <span class="screen-reader-text"><?php _e( 'Back', 'easingslider' ); ?></span>
12
- </span>
13
- </div>
14
-
15
- <div class="wp-full-overlay-sidebar-content" tabindex="-1">
16
- <div id="customize-info" class="accordion-section customize-section">
17
- <div class="accordion-section-title customize-section-title" aria-label="Theme Customizer Options" tabindex="0">
18
- <span class="preview-notice"><?php printf( __( 'You are customizing <strong class="theme-name">%s</strong>', 'easingslider' ), $slider->post_title ); ?></span>
19
- <p>
20
- <span class="preview-notice"><?php _e( 'Change to another slider', 'easingslider' ); ?></span>
21
- <select name="slider_id" id="change-slider" class="widefat">
22
- <?php foreach ( $sliders as $_slider ) : ?>
23
- <option value="<?php echo esc_attr( $_slider->ID ); ?>" <?php selected( $slider->ID, $_slider->ID ); ?>><?php echo esc_html( $_slider->post_title ); ?></option>
24
- <?php endforeach; ?>
25
- </select>
26
- </p>
27
- </div>
28
- </div>
29
- <div id="customize-theme-controls" class="accordion-container">
30
- <ul>
31
- <li class="control-section accordion-section customize-section">
32
- <h3 class="accordion-section-title customize-section-title" tabindex="0" title=""><?php _e( 'Next & Previous Arrows', 'easingslider' ); ?></h3>
33
- <ul class="accordion-section-content customize-section-content">
34
- <li class="customize-control customize-control-text">
35
- <label>
36
- <span class="customize-control-title"><?php _e( '"Next" Arrow Image', 'easingslider' ); ?></span>
37
- <input type="text" name="arrows[next]" data-selector=".easingslider-next" data-property="background-image" value="<?php echo esc_attr( $slider->customizations->arrows->next ); ?>">
38
- </label>
39
- </li>
40
- <li class="customize-control customize-control-text">
41
- <label>
42
- <span class="customize-control-title"><?php _e( '"Previous" Arrow Image', 'easingslider' ); ?></span>
43
- <input type="text" name="arrows[prev]" data-selector=".easingslider-prev" data-property="background-image" value="<?php echo esc_attr( $slider->customizations->arrows->prev ); ?>">
44
- </label>
45
- </li>
46
- <li class="customize-control customize-control-text">
47
- <label>
48
- <span class="customize-control-title"><?php _e( 'Width', 'easingslider' ); ?></span>
49
- <input type="number" min="0" step="1" name="arrows[width]" style="width: 90%" data-selector=".easingslider-arrows" data-property="width" value="<?php echo esc_attr( $slider->customizations->arrows->width ); ?>"> px
50
- </label>
51
- </li>
52
- <li class="customize-control customize-control-text">
53
- <label>
54
- <span class="customize-control-title"><?php _e( 'Height', 'easingslider' ); ?></span>
55
- <input type="number" min="0" step="1" name="arrows[height]" style="width: 90%" data-selector=".easingslider-arrows" data-property="height" value="<?php echo esc_attr( $slider->customizations->arrows->height ); ?>"> px
56
- </label>
57
- </li>
58
- </ul>
59
- </li>
60
-
61
- <li class="control-section accordion-section customize-section">
62
- <h3 class="accordion-section-title customize-section-title" tabindex="0" title=""><?php _e( 'Pagination Icons', 'easingslider' ); ?></h3>
63
- <ul class="accordion-section-content customize-section-content">
64
- <li class="customize-control customize-control-text">
65
- <label>
66
- <span class="customize-control-title"><?php _e( '"Inactive" Image', 'easingslider' ); ?></span>
67
- <input type="text" name="pagination[inactive]" data-selector=".easingslider-icon" data-property="background-image" value="<?php echo esc_attr( $slider->customizations->pagination->inactive ); ?>">
68
- </label>
69
- </li>
70
- <li class="customize-control customize-control-text">
71
- <label>
72
- <span class="customize-control-title"><?php _e( '"Active" Image', 'easingslider' ); ?></span>
73
- <input type="text" name="pagination[active]" data-selector=".easingslider-icon.active" data-property="background-image" value="<?php echo esc_attr( $slider->customizations->pagination->active ); ?>">
74
- </label>
75
- </li>
76
- <li class="customize-control customize-control-text">
77
- <label>
78
- <span class="customize-control-title"><?php _e( 'Icon Width', 'easingslider' ); ?></span>
79
- <input type="number" min="0" step="1" name="pagination[width]" style="width: 90%" data-selector=".easingslider-icon" data-property="width" value="<?php echo esc_attr( $slider->customizations->pagination->width ); ?>"> px
80
- </label>
81
- </li>
82
- <li class="customize-control customize-control-text">
83
- <label>
84
- <span class="customize-control-title"><?php _e( 'Icon Height', 'easingslider' ); ?></span>
85
- <input type="number" min="0" step="1" name="pagination[height]" style="width: 90%" data-selector=".easingslider-icon" data-property="height" value="<?php echo esc_attr( $slider->customizations->pagination->height ); ?>"> px
86
- </label>
87
- </li>
88
- </ul>
89
- </li>
90
-
91
- <li class="control-section accordion-section customize-section">
92
- <h3 class="accordion-section-title customize-section-title" tabindex="0" title=""><?php _e( 'Border', 'easingslider' ); ?></h3>
93
- <ul class="accordion-section-content customize-section-content">
94
- <li class="customize-control customize-control-text">
95
- <label>
96
- <span class="customize-control-title"><?php _e( 'Color', 'easingslider' ); ?></span>
97
- <input type="text" name="border[color]" class="color-picker-hex" data-selector=".easingslider" data-property="border-color" data-default="#000" value="<?php echo esc_attr( $slider->customizations->border->color ); ?>">
98
- </label>
99
- </li>
100
- <li class="customize-control customize-control-text">
101
- <label>
102
- <span class="customize-control-title"><?php _e( 'Width', 'easingslider' ); ?></span>
103
- <input type="number" min="0" step="1" name="border[width]" style="width: 90%" data-selector=".easingslider" data-property="border-width" value="<?php echo esc_attr( $slider->customizations->border->width ); ?>"> px
104
- </label>
105
- </li>
106
- <li class="customize-control customize-control-text">
107
- <label>
108
- <span class="customize-control-title"><?php _e( 'Radius', 'easingslider' ); ?></span>
109
- <input type="number" min="0" step="1" name="border[radius]" style="width: 90%" data-selector=".easingslider" data-property="border-radius" value="<?php echo esc_attr( $slider->customizations->border->radius ); ?>"> px
110
- </label>
111
- </li>
112
- </ul>
113
- </li>
114
-
115
- <li class="control-section accordion-section customize-section">
116
- <h3 class="accordion-section-title customize-section-title" tabindex="0" title=""><?php _e( 'Drop Shadow', 'easingslider' ); ?></h3>
117
- <ul class="accordion-section-content customize-section-content">
118
- <li class="customize-control customize-control-text">
119
- <label>
120
- <span class="customize-control-title"><?php _e( 'Display a Drop Shadow', 'easingslider' ); ?></span>
121
- <label for="shadow-enabled-true"><input type="radio" name="shadow[enabled]" id="shadow-enabled-true" data-selector=".easingslider-shadow" data-property="display" value="true" style="margin: 0 3px 0 0;" <?php checked( $slider->customizations->shadow->enabled, true ); ?>><?php _e( 'True', 'easingslider' ); ?></label>
122
- <label for="shadow-enabled-false"><input type="radio" name="shadow[enabled]" id="shadow-enabled-false" data-selector=".easingslider-shadow" data-property="display" value="false" style="margin: 0 3px 0 20px;" <?php checked( $slider->customizations->shadow->enabled, false ); ?>><?php _e( 'False', 'easingslider' ); ?></label>
123
- </label>
124
- </li>
125
- <li class="customize-control customize-control-text">
126
- <label>
127
- <span class="customize-control-title"><?php _e( 'Shadow Image', 'easingslider' ); ?></span>
128
- <input type="text" name="shadow[image]" data-selector=".easingslider-shadow img" data-property="src" value="<?php echo esc_attr( $slider->customizations->shadow->image ); ?>">
129
- </label>
130
- </li>
131
- </ul>
132
- </li>
133
- </ul>
134
- </div>
135
- </div>
136
-
137
- <div id="customize-footer-actions" class="wp-full-overlay-footer">
138
- <a href="#" class="collapse-sidebar button-secondary" title="<?php _e( 'Collapse Sidebar', 'easingslider' ); ?>">
139
- <span class="collapse-sidebar-arrow"></span>
140
- <span class="collapse-sidebar-label"><?php _e( 'Collapse', 'easingslider' ); ?></span>
141
- </a>
142
- </div>
143
-
144
- <input type="hidden" name="id" value="<?php echo esc_attr( $slider->ID ); ?>">
145
- <input type="hidden" name="customizations" id="customizations" value="">
146
- <?php /** This ensures that the JSON is encoded correctly. Using PHP JSON encode can cause magic quote issues */ ?>
147
- <script type="text/javascript">document.getElementById('customizations').value = '<?php echo addslashes( json_encode( null ) ); ?>';</script>
148
- </form>
149
-
150
- <div id="customize-preview" class="wp-full-overlay-main" style="position: relative;">
151
- <?php
152
- /**
153
- * Display the slider
154
- */
155
- if ( function_exists( 'easingslider' ) ) {
156
- easingslider( $slider->ID );
157
- }
158
- ?>
159
- </div>
160
- </div>
161
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/discover-extensions.php DELETED
@@ -1,26 +0,0 @@
1
- <div class="wrap">
2
- <h2>
3
- <?php _e( 'Extensions for Easing Slider', 'easingslider' ); ?>
4
-
5
- <a href="http://easingslider.com/extensions" target="_blank" class="add-new-h2">
6
- <?php _e( 'Browse All', 'easingslider' ); ?>
7
- </a>
8
- </h2>
9
-
10
- <p><?php _e( 'These extensions enhance Easing Slider, adding new features, providing new slide types and integrating Easing Slider with other plugins.', 'easingslider' ); ?></p>
11
-
12
- <?php if ( $extensions ) : ?>
13
- <?php foreach ( $extensions as $extension ) : ?>
14
- <div class="extension">
15
- <a href="<?php echo esc_attr( $extension->link ); ?>" title="<?php echo esc_attr( $extension->title ); ?>">
16
- <img src="<?php echo esc_attr( $extension->image ); ?>" class="attachment-showcase wp-post-image" alt="<?php echo esc_attr( $extension->title ); ?>" title="<?php echo esc_attr( $extension->title ); ?>" />
17
- </a>
18
- <h3 class="extension-title"><?php echo esc_html( $extension->title ); ?></h3>
19
- <p><?php echo esc_attr( $extension->content ); ?></p>
20
- <a href="<?php echo esc_attr( $extension->link ); ?>" title="<?php echo esc_attr( $extension->title ); ?>" class="button-primary"><?php _e( 'Learn More &rarr;', 'easingslider' ); ?></a>
21
- </div>
22
- <?php endforeach; ?>
23
- <?php else : ?>
24
- <p><?php printf( __( 'There was an error retrieving the extensions list from the server. Please try again later. <a href="%s" target="_blank">Click here</a> to view all extensions on our website.', 'easingslider' ), 'http://easingslider.com/extensions' ); ?></p>
25
- <?php endif; ?>
26
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/edit-settings.php DELETED
@@ -1,40 +0,0 @@
1
- <div class="wrap">
2
- <h2 class="nav-tab-wrapper">
3
- <?php foreach ( $tabs as $slug => $label ) : ?>
4
- <a href="admin.php?page=<?php echo esc_attr( $page ); ?>&amp;tab=<?php echo esc_attr( $slug ); ?>" class="nav-tab <?php echo ( $current_tab == $slug ) ? 'nav-tab-active' : ''; ?>"><?php echo esc_html( $label ); ?></a>
5
- <?php endforeach; ?>
6
- </h2>
7
-
8
- <form name="post" action="admin.php?page=<?php echo esc_attr( $page ); ?>&amp;tab=<?php echo $current_tab; ?>" method="post">
9
- <?php
10
- /**
11
- * Security nonce field
12
- */
13
- wp_nonce_field( 'save' );
14
- ?>
15
-
16
- <div class="main-panel">
17
- <?php
18
- /**
19
- * Before panel action
20
- */
21
- do_action( "easingslider_before_{$current_tab}_settings", $settings );
22
-
23
- /**
24
- * Load the appropriate tab subview, or trigger an action if otherwise.
25
- * This approach allows extensions to add their own "Settings" panels.
26
- */
27
- easingslider_partial_or_action( "edit-settings_{$current_tab}", $settings );
28
-
29
- /**
30
- * After panel action
31
- */
32
- do_action( "easingslider_after_{$current_tab}_settings", $settings );
33
- ?>
34
- </div>
35
-
36
- <p class="submit">
37
- <input type="submit" name="save" class="button button-primary button-large" id="save" accesskey="p" value="<?php _e( 'Save Settings', 'easingslider' ); ?>">
38
- </p>
39
- </form>
40
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/edit-settings_general.php DELETED
@@ -1,65 +0,0 @@
1
- <table class="form-table">
2
- <tbody>
3
- <tr>
4
- <th scope="row"><?php _e( 'Asset Loading', 'easingslider' ); ?></th>
5
- <td>
6
- <label for="assets_header">
7
- <input type="radio" name="settings[load_assets]" id="assets_header" value="header" <?php checked( $settings->load_assets, 'header' ); ?>>
8
- <span><?php _e( 'Compatibility (header)', 'easingslider' ); ?></span>
9
- </label>
10
-
11
- <label for="assets_footer">
12
- <input type="radio" name="settings[load_assets]" id="assets_footer" value="footer" <?php checked( $settings->load_assets, 'footer' ); ?>>
13
- <span><?php _e( 'Optimized (footer)', 'easingslider' ); ?></span>
14
- </label>
15
-
16
- <p class="description"><?php _e( 'This option controls where the plugin\'s scripts and styling are loaded. "Compatibility" will load them in the page header, which is less performant but also less likely to suffer conflicts with other plugins. "Optimized" conditionally loads CSS and JS in the page footer, which is better for performance, but more likely to encounter errors. We recommend trying "Optimized" and reverting back if you encounter any issues.', 'easingslider' ); ?></p>
17
- </td>
18
- </tr>
19
- </tbody>
20
- </table>
21
-
22
- <hr><h3><?php _e( 'Data Settings', 'easingslider' ); ?></h3>
23
-
24
- <table class="form-table">
25
- <tbody>
26
- <tr>
27
- <th scope="row"><?php _e( 'Remove data on uninstall?', 'easingslider' ); ?></th>
28
- <td>
29
- <label for="remove_data">
30
- <input type="hidden" name="settings[remove_data]" value="false">
31
- <input type="checkbox" name="settings[remove_data]" id="remove_data" value="true" <?php checked( $settings->remove_data, true ); ?>>
32
- <span style="display: inline;"><?php _e( 'Check this box if you would like Easing Slider to completely remove all of its data when the plugin is deleted.', 'easingslider' ); ?></span>
33
- </label>
34
-
35
- <p class="description"><?php _e( 'Be careful before enabling this option, as the data cannot be recovered once it has been deleted.', 'easingslider' ); ?></p>
36
- </td>
37
- </tr>
38
- </tbody>
39
- </table>
40
-
41
- <hr><h3><?php _e( 'Installation Settings', 'easingslider' ); ?></h3>
42
-
43
- <table class="form-table">
44
- <tbody>
45
- <tr>
46
- <th scope="row"><?php _e( 'PHP Version', 'easingslider' ); ?></th>
47
- <td><?php echo phpversion(); ?></td>
48
- </tr>
49
-
50
- <tr>
51
- <th scope="row"><?php _e( 'MySQL Version', 'easingslider' ); ?></th>
52
- <td><?php global $wpdb; echo $wpdb->get_var( 'SELECT VERSION()' ); ?></td>
53
- </tr>
54
-
55
- <tr>
56
- <th scope="row"><?php _e( 'WordPress Version', 'easingslider' ); ?></th>
57
- <td><?php global $wp_version; echo $wp_version; ?></td>
58
- </tr>
59
-
60
- <tr>
61
- <th scope="row"><?php _e( 'Plugin Version', 'easingslider' ); ?></th>
62
- <td><?php echo Easing_Slider::$version; ?></td>
63
- </tr>
64
- </tbody>
65
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/edit-settings_licenses.php DELETED
@@ -1,12 +0,0 @@
1
- <p style="padding-top: 10px;"><?php printf( __( 'Below you can register your extension licenses. This is required to enable extension updates. You can browse all available extensions <a href="%s">here</a>.', 'easingslider' ), admin_url( 'admin.php?page=easingslider_discover_extensions' ) ); ?></p>
2
-
3
- <table class="form-table">
4
- <tbody>
5
- <?php
6
- /**
7
- * Print license settings fields
8
- */
9
- do_action( 'easingslider_print_license_fields' );
10
- ?>
11
- </tbody>
12
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
partials/edit-slider.php DELETED
@@ -1,73 +0,0 @@
1
- <div class="wrap">
2
- <form id="slider" name="slider" action="admin.php?page=<?php echo esc_attr( $page ); if ( isset( $id ) ) { echo "&amp;edit=". esc_attr( $id ) .""; } ?>" method="post">
3
- <?php
4
- /**
5
- * Security nonce field
6
- */
7
- wp_nonce_field( 'save' );
8
- ?>
9
-
10
- <h2>
11
- <?php if ( isset( $id ) ) : ?>
12
- <?php _e( 'Edit Slider', 'easingslider' ); ?>
13
- <a href="admin.php?page=easingslider_publish_slider" class="add-new-h2"><?php _e( 'Add New', 'easingslider' ); ?></a>
14
- <?php else : ?>
15
- <?php _e( 'Add New Slider', 'easingslider' ); ?>
16
- <?php endif; ?>
17
- </h2>
18
-
19
- <div class="toolbar-container">
20
- <div class="media-toolbar wp-filter">
21
- <div class="media-toolbar-secondary title-form">
22
- <label for="post_title"><?php _e( 'Name:', 'easingslider' ); ?></label>
23
- <input type="text" name="post_title" id="post_title" autocomplete="off" placeholder="<?php _e( 'Enter a slider name', 'easingslider' ); ?>" value="<?php echo esc_attr( $slider->post_title ); ?>">
24
- <a href="#" id="select-all" class="button media-button button-large hidden"><?php _e( 'Select All', 'easingslider' ); ?></a>
25
- </div>
26
-
27
- <div class="media-toolbar-primary">
28
- <label for="randomize" class="randomize">
29
- <input type="hidden" name="general[randomize]" value="false">
30
- <input type="checkbox" id="randomize" name="general[randomize]" value="true" <?php checked( $slider->general->randomize, true ); ?>><span style="display: inline;"><?php _e( 'Randomize the slide order', 'easingslider' ); ?></span>
31
- </label>
32
- <a href="#" id="add-slides" class="button media-button button-primary button-large"><?php _e( 'Add Slides', 'easingslider' ); ?></a>
33
- <a href="#" id="bulk-select" class="button media-button button-large select-mode-toggle-button"><?php _e( 'Bulk Select', 'easingslider' ); ?></a>
34
- <a href="#" id="cancel-select" class="button media-button button-large select-mode-toggle-button hidden"><?php _e( 'Cancel Selection', 'easingslider' ); ?></a>
35
- <a href="#" id="delete-slides" class="button media-button button-primary button-large hidden"><?php _e( 'Delete Selected', 'easingslider' ); ?></a>
36
- </div>
37
- </div>
38
- </div>
39
-
40
- <div class="main-container clearfix">
41
- <div class="slides-container">
42
- <div class="media-frame wp-core-ui mode-grid hide-menu">
43
- <div class="media-frame-content" data-columns="5">
44
- <div id="slides-browser" class="attachments-browser hide-sidebar">
45
- <?php
46
- /**
47
- * Slides are dynamically added using Backbone.js here.
48
- */
49
- ?>
50
- </div>
51
- </div>
52
- </div>
53
- </div>
54
-
55
- <div class="settings-container">
56
- <?php
57
- /**
58
- * Keep our settings sidebar in a separate file for clarity. Woohoo!
59
- */
60
- require 'edit-slider_sidebar.php';
61
- ?>
62
- </div>
63
- </div>
64
-
65
- <?php
66
- /**
67
- * This ensures that the slide's JSON is encoded correctly.
68
- * Using PHP JSON encode can cause magic quote issues.
69
- */
70
- ?>
71
- <script type="text/javascript">var slides = '<?php echo addslashes( json_encode( $slider->slides ) ); ?>';</script>
72
- </form>
73
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/edit-slider_sidebar.php DELETED
@@ -1,410 +0,0 @@
1
- <?php
2
- /**
3
- * Allow for additional boxes
4
- */
5
- do_action( 'easingslider_before_edit_slider_sidebar', $slider );
6
- ?>
7
-
8
- <!-- Publish -->
9
- <div class="widgets-holder-wrap fixed">
10
- <div class="sidebar-name">
11
- <h3><?php _e( 'Publish', 'easingslider' ); ?></h3>
12
- </div>
13
- <div class="sidebar-content widgets-sortables clearfix">
14
- <?php
15
- /**
16
- * Allow for additional options
17
- */
18
- do_action( 'easingslider_publish_metabox_top', $slider );
19
- ?>
20
-
21
- <div class="misc-pub-section curtime misc-pub-curtime">
22
- <span id="timestamp">
23
- <?php if ( ! empty( $slider->ID ) ) : ?>
24
- <?php printf( __( 'Published on: <b>%s</b>', 'easingslider' ), date( 'M j, Y @ G:i', strtotime( $slider->post_date ) ) ); ?>
25
- <?php else : ?>
26
- <?php printf( __( 'Not published yet.', 'easingslider' ) ); ?>
27
- <?php endif; ?>
28
- </span>
29
- </div>
30
-
31
- <?php
32
- /**
33
- * Allow for additional options
34
- */
35
- do_action( 'easingslider_publish_metabox_bottom', $slider );
36
- ?>
37
- </div>
38
- <div id="major-publishing-actions">
39
- <div id="publishing-action">
40
- <span class="spinner"></span>
41
- <input type="submit" name="save" class="button button-primary button-large" id="save" accesskey="p" disabled="disabled" value="<?php _e( 'Update', 'easingslider' ); ?>">
42
- </div>
43
- <div class="clear"></div>
44
- </div>
45
- </div>
46
-
47
- <!-- Support Easing Slider -->
48
- <?php if ( apply_filters( 'easingslider_show_advert', __return_true() ) ) : ?>
49
- <?php
50
- /**
51
- * Create the Tweet URL
52
- */
53
- $tweet_url = add_query_arg( array(
54
- 'text' => __( 'Check out Easing Slider, an easy to use free slider plugin for WordPress.', 'easingslider' ),
55
- 'url' => 'http://easingslider.com/',
56
- 'via' => 'EasingSlider',
57
- 'hashtags' => 'wordpress',
58
- ), 'https://twitter.com/intent/tweet' );
59
- ?>
60
-
61
- <div class="widgets-holder-wrap fixed">
62
- <a href="http://easingslider.com/addons/pro-bundle" target="_blank">
63
- <img src="<?php echo plugin_dir_url( Easing_Slider::$file ) . 'images/pro-bundle.png'; ?>" alt="\"Pro\" add-on bundle" style="display: block; width: 100%;" />
64
- </a>
65
-
66
- <div class="sidebar-content widgets-sortables clearfix">
67
- <p><?php printf( __( 'Like Easing Slider? <br><a href="%s">Support us with a Tweet &raquo;</a>', 'easingslider' ), $tweet_url ); ?>
68
- <p><?php printf( __( 'Remove this ad? <br><a href="%s" target="_blank">Purchase a premium add-on &raquo;</a>', 'easingslider' ), 'http://easingslider.com/addons' ); ?></p>
69
- </div>
70
- </div>
71
- <?php endif; ?>
72
-
73
- <!-- Dimensions -->
74
- <div class="widgets-holder-wrap">
75
- <div class="sidebar-name">
76
- <div class="sidebar-name-arrow"></div>
77
- <h3><?php _e( 'Dimensions', 'easingslider' ); ?></h3>
78
- </div>
79
- <div class="sidebar-content widgets-sortables clearfix">
80
- <?php
81
- /**
82
- * Allow for additional options
83
- */
84
- do_action( 'easingslider_dimensions_metabox_top', $slider );
85
- ?>
86
-
87
- <div class="dimension-settings">
88
- <div class="field half">
89
- <label for="width">
90
- <span><?php _e( 'Width:', 'easingslider' ); ?></span>
91
- <input type="number" name="dimensions[width]" id="width" value="<?php echo esc_attr( $slider->dimensions->width ); ?>">
92
- </label>
93
- </div>
94
- <div class="field half">
95
- <label for="height">
96
- <span><?php _e( 'Height:', 'easingslider' ); ?></span>
97
- <input type="number" name="dimensions[height]" id="height" value="<?php echo esc_attr( $slider->dimensions->height ); ?>">
98
- </label>
99
- </div>
100
- <p class="description"><?php _e( 'Slideshow "width" and "height" values (in pixels).', 'easingslider' ); ?></p>
101
- </div>
102
-
103
- <div>
104
- <div class="field">
105
- <label for="responsive">
106
- <input type="hidden" name="dimensions[responsive]" value="false">
107
- <input type="checkbox" name="dimensions[responsive]" id="responsive" value="true" <?php checked( $slider->dimensions->responsive, true ); ?>><span style="display: inline;"><?php _e( 'Make this slider responsive.', 'easingslider' ); ?></span>
108
- </label>
109
- </div>
110
- <p class="description"><?php _e( 'Check this option to make this slider responsive. If enabled, the "width" and "height" values above will act as maximums.', 'easingslider' ); ?></p>
111
- </div>
112
-
113
- <div>
114
- <a href="#" class="show-advanced-options"><?php printf( '+ %s', __( 'Advanced Options', 'easingslider' ) ); ?></a>
115
- <div class="advanced-options hidden">
116
- <div>
117
- <div class="field">
118
- <label for="full_width">
119
- <input type="hidden" name="dimensions[full_width]" value="false">
120
- <input type="checkbox" name="dimensions[full_width]" id="full_width" value="true" <?php checked( $slider->dimensions->full_width, true ); ?>><span style="display: inline;"><?php _e( 'Enable 100% full width.', 'easingslider' ); ?></span>
121
- </label>
122
- </div>
123
- <p class="description"><?php _e( 'When enabled, the slider will set its container width to 100%. This option works for responsive sliders only. For best results, it\'s recommend that you disable image resizing when this option is enabled.', 'easingslider' ); ?></p>
124
- </div>
125
- <div>
126
- <div class="field">
127
- <label for="image_resizing">
128
- <input type="hidden" name="dimensions[image_resizing]" value="false">
129
- <input type="checkbox" name="dimensions[image_resizing]" id="image_resizing" value="true" <?php checked( $slider->dimensions->image_resizing, true ); ?>><span style="display: inline;"><?php _e( 'Crop & resize images to fit slider.', 'easingslider' ); ?></span>
130
- </label>
131
- </div>
132
- <p class="description"><?php _e( 'Tick this option to have the slider crop & resize images to fit the slider dimensions. This will only work with images from the WordPress Media Library.', 'easingslider' ); ?></p>
133
- </div>
134
- <div>
135
- <div class="field">
136
- <label for="keep_ratio">
137
- <input type="hidden" name="dimensions[keep_ratio]" value="false">
138
- <input type="checkbox" name="dimensions[keep_ratio]" id="keep_ratio" value="true" <?php checked( $slider->dimensions->keep_ratio, true ); ?>><span style="display: inline;"><?php _e( 'Proportionally resize slider.', 'easingslider' ); ?></span>
139
- </label>
140
- </div>
141
- <p class="description"><?php _e( 'This option enables proportional slider resizing for responsive sliders. This maintains the aspect ratio. Disable this option for fixed height sliders.', 'easingslider' ); ?></p>
142
- </div>
143
- <div>
144
- <div class="field">
145
- <label for="background_images">
146
- <input type="hidden" name="dimensions[background_images]" value="false">
147
- <input type="checkbox" name="dimensions[background_images]" id="background_images" value="true" <?php checked( $slider->dimensions->background_images, true ); ?>><span style="display: inline;"><?php _e( 'Use background images.', 'easingslider' ); ?></span>
148
- </label>
149
- </div>
150
- <p class="description"><?php _e( 'Enable this option if you want the slider to use CSS background images for image slides.', 'easingslider' ); ?></p>
151
- </div>
152
- </div>
153
- </div>
154
-
155
- <?php
156
- /**
157
- * Allow for additional options
158
- */
159
- do_action( 'easingslider_dimensions_metabox_bottom', $slider );
160
- ?>
161
- </div>
162
- </div>
163
-
164
- <!-- Transitions -->
165
- <div class="widgets-holder-wrap closed">
166
- <div class="sidebar-name">
167
- <div class="sidebar-name-arrow"></div>
168
- <h3><?php _e( 'Transitions', 'easingslider' ); ?></h3>
169
- </div>
170
- <div class="sidebar-content widgets-sortables clearfix" style="display: none;">
171
- <?php
172
- /**
173
- * Allow for additional options
174
- */
175
- do_action( 'easingslider_transitions_metabox_top', $slider );
176
- ?>
177
-
178
- <div>
179
- <div class="field">
180
- <label for="effect">
181
- <span><?php _e( 'Effect:', 'easingslider' ); ?></span>
182
- <select name="transitions[effect]" id="effect">
183
- <?php foreach ( $slider->get_transitions() as $transition => $label ) : ?>
184
- <option value="<?php echo esc_attr( $transition ); ?>" <?php selected( $slider->transitions->effect, $transition ); ?>><?php echo esc_html( $label ); ?></option>
185
- <?php endforeach; ?>
186
- </select>
187
- </label>
188
- </div>
189
- <p class="description"><?php _e( 'Choose the transition effect you would like to use.', 'easingslider' ); ?></p>
190
- </div>
191
- <div class="divider"></div>
192
-
193
- <div>
194
- <div class="field">
195
- <label for="duration">
196
- <span><?php _e( 'Duration:', 'easingslider' ); ?></span>
197
- <input type="number" name="transitions[duration]" id="duration" value="<?php echo esc_attr( $slider->transitions->duration ); ?>">
198
- </label>
199
- </div>
200
- <p class="description"><?php _e( 'Sets the duration (in milliseconds) for the slideshow transition.', 'easingslider' ); ?></p>
201
- </div>
202
-
203
- <?php
204
- /**
205
- * Allow for additional options
206
- */
207
- do_action( 'easingslider_transitions_metabox_bottom', $slider );
208
- ?>
209
- </div>
210
- </div>
211
-
212
- <!-- Next & Previous Arrows -->
213
- <div class="widgets-holder-wrap closed">
214
- <div class="sidebar-name">
215
- <div class="sidebar-name-arrow"></div>
216
- <h3><?php _e( 'Next & Previous Arrows', 'easingslider' ); ?></h3>
217
- </div>
218
- <div class="sidebar-content widgets-sortables" style="display: none;">
219
- <?php
220
- /**
221
- * Allow for additional options
222
- */
223
- do_action( 'easingslider_arrows_metabox_top', $slider );
224
- ?>
225
-
226
- <div>
227
- <div class="radio clearfix">
228
- <span><?php _e( 'Arrows:', 'easingslider' ); ?></span>
229
- <div class="buttons">
230
- <label for="arrows-enable"><input type="radio" name="navigation[arrows]" id="arrows-enable" value="true" <?php checked( $slider->navigation->arrows, true ); ?>>
231
- <span><?php _e( 'Enable', 'easingslider' ); ?></span>
232
- </label>
233
- <label for="arrows-disable"><input type="radio" name="navigation[arrows]" id="arrows-disable" value="false" <?php checked( $slider->navigation->arrows, false ); ?>>
234
- <span><?php _e( 'Disable', 'easingslider' ); ?></span>
235
- </label>
236
- </div>
237
- </div>
238
- <p class="description"><?php _e( 'Toggles the next and previous slide arrows.', 'easingslider' ); ?></p>
239
- </div>
240
- <div class="divider"></div>
241
-
242
- <div>
243
- <div class="radio clearfix">
244
- <span><?php _e( 'On Hover:', 'easingslider' ); ?></span>
245
- <div class="buttons">
246
- <label for="arrows-hover-true"><input type="radio" name="navigation[arrows_hover]" id="arrows-hover-true" value="true" <?php checked( $slider->navigation->arrows_hover, true ); ?>>
247
- <span><?php _e( 'True', 'easingslider' ); ?></span>
248
- </label>
249
- <label for="arrows-hover-false"><input type="radio" name="navigation[arrows_hover]" id="arrows-hover-false" value="false" <?php checked( $slider->navigation->arrows_hover, false ); ?>>
250
- <span><?php _e( 'False', 'easingslider' ); ?></span>
251
- </label>
252
- </div>
253
- </div>
254
- <p class="description"><?php _e( 'Set to "True" to only show the arrows when the user hovers over the slideshow.', 'easingslider' ); ?></p>
255
- </div>
256
- <div class="divider"></div>
257
-
258
- <div>
259
- <div class="field">
260
- <label for="arrows_position">
261
- <span><?php _e( 'Position:', 'easingslider' ); ?></span>
262
- <select name="navigation[arrows_position]" id="arrows_position">
263
- <option value="inside" <?php selected( $slider->navigation->arrows_position, 'inside' ); ?>><?php _e( 'Inside', 'easingslider' ); ?></option>
264
- <option value="outside" <?php selected( $slider->navigation->arrows_position, 'outside' ); ?>><?php _e( 'Outside', 'easingslider' ); ?></option>
265
- </select>
266
- </label>
267
- </div>
268
- <p class="description"><?php _e( 'Select a position for the arrows.', 'easingslider' ); ?></p>
269
- </div>
270
-
271
- <?php
272
- /**
273
- * Allow for additional options
274
- */
275
- do_action( 'easingslider_arrows_metabox_bottom', $slider );
276
- ?>
277
- </div>
278
- </div>
279
-
280
- <!-- Pagination Icons -->
281
- <div class="widgets-holder-wrap closed">
282
- <div class="sidebar-name">
283
- <div class="sidebar-name-arrow"></div>
284
- <h3><?php _e( 'Pagination Icons', 'easingslider' ); ?></h3>
285
- </div>
286
- <div class="sidebar-content widgets-sortables" style="display: none;">
287
- <?php
288
- /**
289
- * Allow for additional options
290
- */
291
- do_action( 'easingslider_pagination_metabox_top', $slider );
292
- ?>
293
-
294
- <div>
295
- <div class="radio clearfix">
296
- <span><?php _e( 'Pagination:', 'easingslider' ); ?></span>
297
- <div class="buttons">
298
- <label for="pagination-enable"><input type="radio" name="navigation[pagination]" id="pagination-enable" value="true" <?php checked( $slider->navigation->pagination, true ); ?>>
299
- <span><?php _e( 'Enable', 'easingslider' ); ?></span>
300
- </label>
301
- <label for="pagination-disable"><input type="radio" name="navigation[pagination]" id="pagination-disable" value="false" <?php checked( $slider->navigation->pagination, false ); ?>>
302
- <span><?php _e( 'Disable', 'easingslider' ); ?></span>
303
- </label>
304
- </div>
305
- </div>
306
- <p class="description"><?php _e( 'Enable/Disable the Pagination Icons. Each icon represents a slide in their respective order.', 'easingslider' ); ?></p>
307
- </div>
308
- <div class="divider"></div>
309
-
310
- <div>
311
- <div class="radio clearfix">
312
- <span><?php _e( 'On Hover:', 'easingslider' ); ?></span>
313
- <div class="buttons">
314
- <label for="pagination-hover-true"><input type="radio" name="navigation[pagination_hover]" id="pagination-hover-true" value="true" <?php checked( $slider->navigation->pagination_hover, true ); ?>>
315
- <span><?php _e( 'True', 'easingslider' ); ?></span>
316
- </label>
317
- <label for="pagination-hover-false"><input type="radio" name="navigation[pagination_hover]" id="pagination-hover-false" value="false" <?php checked( $slider->navigation->pagination_hover, false ); ?>>
318
- <span><?php _e( 'False', 'easingslider' ); ?></span>
319
- </label>
320
- </div>
321
- </div>
322
- <p class="description"><?php _e( 'Set to "True" to only show the pagination when the user hovers over the slideshow.', 'easingslider' ); ?></p>
323
- </div>
324
- <div class="divider"></div>
325
-
326
- <div>
327
- <div class="field">
328
- <label for="pagination_position">
329
- <span><?php _e( 'Position:', 'easingslider' ); ?></span>
330
- <select name="navigation[pagination_position]" id="pagination_position" style="width: 45%; float: left;">
331
- <option value="inside" <?php selected( $slider->navigation->pagination_position, 'inside' ); ?>><?php _e( 'Inside', 'easingslider' ); ?></option>
332
- <option value="outside" <?php selected( $slider->navigation->pagination_position, 'outside' ); ?>><?php _e( 'Outside', 'easingslider' ); ?></option>
333
- </select>
334
- <select name="navigation[pagination_location]" id="pagination_location" style="width: 45%; float: left; margin-left: 10px;">
335
- <option value="top-left" <?php selected( $slider->navigation->pagination_location, 'top-left' ); ?>><?php _e( 'Top Left', 'easingslider' ); ?></option>
336
- <option value="top-right" <?php selected( $slider->navigation->pagination_location, 'top-right' ); ?>><?php _e( 'Top Right', 'easingslider' ); ?></option>
337
- <option value="top-center" <?php selected( $slider->navigation->pagination_location, 'top-center' ); ?>><?php _e( 'Top Center', 'easingslider' ); ?></option>
338
- <option value="bottom-left" <?php selected( $slider->navigation->pagination_location, 'bottom-left' ); ?>><?php _e( 'Bottom Left', 'easingslider' ); ?></option>
339
- <option value="bottom-right" <?php selected( $slider->navigation->pagination_location, 'bottom-right' ); ?>><?php _e( 'Bottom Right', 'easingslider' ); ?></option>
340
- <option value="bottom-center" <?php selected( $slider->navigation->pagination_location, 'bottom-center' ); ?>><?php _e( 'Bottom Center', 'easingslider' ); ?></option>
341
- </select>
342
- </label>
343
- </div>
344
- <p class="description"><?php _e( 'Select a position for the pagination icons.', 'easingslider' ); ?></p>
345
- </div>
346
-
347
- <?php
348
- /**
349
- * Allow for additional options
350
- */
351
- do_action( 'easingslider_pagination_metabox_bottom', $slider );
352
- ?>
353
- </div>
354
- </div>
355
-
356
- <!-- Playback -->
357
- <div class="widgets-holder-wrap closed">
358
- <div class="sidebar-name">
359
- <div class="sidebar-name-arrow"></div>
360
- <h3><?php _e( 'Automatic Playback', 'easingslider' ); ?></h3>
361
- </div>
362
- <div class="sidebar-content widgets-sortables" style="display: none;">
363
- <?php
364
- /**
365
- * Allow for additional options
366
- */
367
- do_action( 'easingslider_playback_metabox_top', $slider );
368
- ?>
369
-
370
- <div>
371
- <div class="radio clearfix">
372
- <span><?php _e( 'Playback:', 'easingslider' ); ?></span>
373
- <div class="buttons">
374
- <label for="playback-enable"><input type="radio" name="playback[enabled]" id="playback-enable" value="true" <?php checked( $slider->playback->enabled, true ); ?>>
375
- <span><?php _e( 'Enable', 'easingslider' ); ?></span>
376
- </label>
377
- <label for="playback-disable"><input type="radio" name="playback[enabled]" id="playback-disable" value="false" <?php checked( $slider->playback->enabled, false ); ?>>
378
- <span><?php _e( 'Disable', 'easingslider' ); ?></span>
379
- </label>
380
- </div>
381
- </div>
382
- <p class="description"><?php _e( 'Enable/Disable slideshow automatic playback.', 'easingslider' ); ?></p>
383
- </div>
384
- <div class="divider"></div>
385
-
386
- <div>
387
- <div class="field">
388
- <label for="playback_pause">
389
- <span><?php _e( 'Pause Duration:', 'easingslider' ); ?></span>
390
- <input type="number" name="playback[pause]" id="playback_pause" value="<?php echo esc_attr( $slider->playback->pause ); ?>">
391
- </label>
392
- </div>
393
- <p class="description"><?php _e( 'Sets the duration (in milliseconds) for the pause between slide transitions.', 'easingslider' ); ?></p>
394
- </div>
395
-
396
- <?php
397
- /**
398
- * Allow for additional options
399
- */
400
- do_action( 'easingslider_playback_metabox_bottom', $slider );
401
- ?>
402
- </div>
403
- </div>
404
-
405
- <?php
406
- /**
407
- * Allow for additional boxes
408
- */
409
- do_action( 'easingslider_after_edit_slider_sidebar', $slider );
410
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/list-sliders.php DELETED
@@ -1,35 +0,0 @@
1
- <div class="wrap">
2
- <h2>
3
- <?php _e( 'Sliders ', 'easingslider' ); ?>
4
- <a href="admin.php?page=easingslider_publish_slider" class="add-new-h2">
5
- <?php _e( 'Add New', 'easingslider' ); ?>
6
- </a>
7
-
8
- <?php if ( isset( $_GET['s'] ) && ! empty( $_GET['s'] ) ) : ?>
9
- <span class="subtitle"><?php printf( __( 'Search results for &#8220;%s&#8221;', 'easingslider' ), esc_attr( $_GET['s'] ) ); ?></span>
10
- <?php endif; ?>
11
- </h2>
12
-
13
- <?php
14
- /**
15
- * Prepare the sliders list table items
16
- */
17
- $list_table->prepare_items();
18
- ?>
19
-
20
- <form id="sliders-list" method="get">
21
- <input type="hidden" name="page" value="<?php echo esc_attr( $page ); ?>" />
22
-
23
- <?php
24
- /**
25
- * Display a search input, allowing us to search through our sliders list.
26
- */
27
- $list_table->search_box( __( 'Search Sliders', 'easingslider' ), 'search_id' );
28
-
29
- /**
30
- * Display the list table
31
- */
32
- $list_table->display();
33
- ?>
34
- </form>
35
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/welcome.php DELETED
@@ -1,18 +0,0 @@
1
- <div class="wrap about-wrap">
2
- <h1><?php printf( __( 'Welcome to Easing Slider %s', 'easingslider' ), $version ); ?></h1>
3
- <div class="about-text"><?php printf( __( 'Thank you for updating to the latest version! Easing Slider %s is ready to help you create beautiful sliders easily, quickly and for free!', 'easingslider' ), $version ); ?></div>
4
- <div class="easingslider-badge"><?php printf( __( 'Version %s', 'easingslider' ), $version ); ?></div>
5
-
6
- <h2 class="nav-tab-wrapper">
7
- <?php foreach ( $tabs as $slug => $tab ) : ?>
8
- <a href="index.php?page=easingslider-<?php echo $tab['slug']; ?>" class="nav-tab <?php echo ( $current_tab == $slug ) ? 'nav-tab-active' : ''; ?>"><?php echo esc_html( $tab['title'] ); ?></a>
9
- <?php endforeach; ?>
10
- </h2>
11
-
12
- <?php
13
- /**
14
- * Load the appropraite subview
15
- */
16
- require plugin_dir_path( __FILE__ ) . "welcome_{$current_tab}.php";
17
- ?>
18
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/welcome_about.php DELETED
@@ -1,48 +0,0 @@
1
- <div class="changelog headline-feature">
2
- <h2 class="about-headline-callout"><?php _e( 'Check out the awesome all new Easing Slider', 'easingslider' ); ?></h2>
3
- <p class="about-text"><?php printf( __( 'We\'ve completely rebuilt Easing Slider from the ground up to be a more stable, modern, easy to use solution for creating sliders on your WordPress blog. There\'s loads of new features, some of which described below. For more information on the changes, <a href="%s" target="_blank">click here</a>.', 'easingslider' ), 'http://easingslider.com/2015/01/new-year-new-easing-slider/' ); ?></p>
4
- </div>
5
-
6
- <div class="changelog">
7
- <div class="feature-section col two-col">
8
- <div class="col-1">
9
- <img src="<?php echo "{$image_dir}/list-screenshot.jpg"; ?>" alt="<?php _e( 'List Screenshot', 'easingslider' ); ?>" class="list-screenshot">
10
- <h3><?php _e( 'Unlimited Sliders', 'easingslider' ); ?></h3>
11
- <p><?php _e( 'Create as many sliders as you like, Easing Slider is no longer limited to just one slider. We\'re now using our own custom post type, a significant improvement for developers.', 'easingslider' ); ?></p>
12
- </div>
13
-
14
- <div class="col-2 last-feature">
15
- <img src="<?php echo "{$image_dir}/interface-screenshot.jpg"; ?>" alt="<?php _e( 'Interface Screenshot', 'easingslider' ); ?>" class="interface-screenshot">
16
- <h3><?php _e( 'Simple Interface', 'easingslider' ); ?></h3>
17
- <p><?php _e( 'The admin interface has been completely revamped to be easier, yet more powerful. The new look admin is instantly familiar, similar in style to the new WordPress Media Library.', 'easingslider' ); ?></p>
18
- </div>
19
- </div>
20
- <hr>
21
-
22
- <div class="feature-section col three-col">
23
- <div class="col-1">
24
- <h4><?php _e( 'Introducing Extensions', 'easingslider' ); ?></h4>
25
- <p><?php _e( 'A vast selection of extensions will soon be available, extending the functionality of Easing Slider beyond what\'s ever been possible before. View them <a href="admin.php?page=easingslider_discover_extensions">here</a>.', 'easingslider' ); ?></p>
26
- </div>
27
-
28
- <div class="col-2">
29
- <h4><?php _e( 'CSS3 Animations', 'easingslider' ); ?></h4>
30
- <p><?php _e( 'The plugin now relies entirely on modern CSS3 animations. This ensures smooth transitions, with graceful fallbacks for older browsers.', 'easingslider' ); ?></p>
31
- </div>
32
-
33
- <div class="col-3 last-feature">
34
- <h4><?php _e( 'Developer Friendly', 'easingslider' ); ?></h4>
35
- <p><?php _e( 'Our entirely new infrastructure provides developers with more power than ever. More actions, filters, and extensions bring unlimited potential.', 'easingslider' ); ?></p>
36
- </div>
37
- </div>
38
- <hr>
39
-
40
- <div class="feature-section">
41
- <h4><?php _e( 'More to come', 'easingslider' ); ?></h4>
42
- <p><?php _e( 'This update is just the beginning - the future will bring even more improvements to Easing Slider. We have plans for dozens of extensions that\'ll extend functionality far beyond what was capable before, ensuring Easing Slider remains the best slider plugin for WordPress.', 'easingslider' ); ?></p>
43
- </div>
44
-
45
- <div class="return-to-dashboard">
46
- <a href="<?php echo admin_url( 'admin.php?page=easingslider_edit_sliders' ); ?>"><?php _e( 'Return to Easing Slider', 'easingslider' ); ?></a>
47
- </div>
48
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/welcome_credits.php DELETED
@@ -1,28 +0,0 @@
1
- <div class="changelog headline-feature">
2
- <h2 class="about-headline-callout credits-headline"><?php _e( 'Want to contribute to Easing Slider? Here\'s how you can.', 'easingslider' ); ?></h2>
3
- </div>
4
-
5
- <div class="changelog" style="margin-bottom: 10px;">
6
- <p><?php printf( __( 'Until now, Easing Slider has been developed solely by <a href="%s" target="_blank">me</a>, Matthew Ruddy, but it\'s time for this to change.', 'easingslider' ), 'http://matthewruddy.com' ); ?></p>
7
-
8
- <p><?php printf( __( 'Now, Easing Slider\'s official channel of development will be managed through <a href="%s" target="_blank">Github</a>, where I hope to encourage involvement from other developers who have a vision for Easing Slider as strong as my own.', 'easingslider' ), 'https://github.com/easingslider/easing-slider' ); ?></p>
9
-
10
- <p><?php printf( __( 'Whether you\'ve encountered a simple bug and want to provide a fix, or you wish to tackle some enhancements or new features, please don\'t hesitate to <a href="%s" target="_blank">get involved</a>. Even if you can\'t code, your feedback is greated appreciated and really important to us, so <a href="%s" target="_blank">get in touch</a>.', 'easingslider'), 'https://github.com/easingslider/easing-slider', 'http://easingslider.com/support' ); ?></p>
11
-
12
- <p><?php printf( __( 'Hopefully soon this page will be vividly decorated with contributors %s.', 'easingslider' ), '<span class="dashicons dashicons-smiley"></span>' ); ?></p>
13
- </div>
14
-
15
- <h4 class="wp-people-group"><?php _e( 'Proudly Built By:', 'easingslider' ); ?></h4>
16
-
17
- <ul class="wp-people-group " id="wp-people-group-project-leaders">
18
- <li class="wp-person" id="wp-person-ryan">
19
- <a href="http://profiles.wordpress.org/matthewruddy"><img src="https://secure.gravatar.com/avatar/3989ea0bb66e20f7694d93c148fc8563?s=80&d=monsterid&r=g" class="gravatar" alt="<?php _e( 'Matthew Ruddy', 'easingslider' ); ?>"></a>
20
- <a class="web" href="http://profiles.wordpress.org/matthewruddy"><?php _e( 'Matthew Ruddy', 'easingslider' ); ?></a>
21
- <span class="title"><?php _e( 'Just an average guy', 'easingslider' ); ?></span>
22
- </li>
23
- </ul>
24
-
25
- <div class="return-to-dashboard">
26
- <a href="https://github.com/easingslider/easing-slider" target="_blank"><?php _e( 'Contribute on Github', 'easingslider' ); ?></a> ·
27
- <a href="http://easingslider.com/support" target="_blank"><?php _e( 'Contact Us', 'easingslider' ); ?></a>
28
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
partials/welcome_getting-started.php DELETED
@@ -1,64 +0,0 @@
1
- <p class="about-description">
2
- <?php _e( 'Use the tips below to get started using Easing Slider. It\'s super quick and easy!', 'easingslider' ); ?>
3
- </p>
4
-
5
- <div class="changelog">
6
- <div class="feature-section col two-col">
7
- <div class="col-1">
8
- <h3><?php _e( 'Creating Your First Slider', 'easingslider' ); ?></h3>
9
-
10
- <h4><a href="<?php echo admin_url( 'admin.php?page=easingslider_edit_sliders' ); ?>"><?php _e( 'Sliders &rarr; Add New', 'easingslider' ); ?></a></h4>
11
- <p><?php _e( 'The "Sliders" menu is your access point for all aspects of Easing Slider. Simply click "Add New" to create your first slider and start adding slides.', 'easingslider' ); ?></p>
12
-
13
- <h4><?php _e( 'Adding Slides', 'easingslider' ); ?></h4>
14
- <p><?php printf( __( 'Click the "Add Slides" button to add image slides from the WordPress Media Library. Other slide types can be purchased from our vast array of extensions <a href="%s">found here</a>.', 'easingslider' ), 'http://easingslider.com/extensions' ); ?></p>
15
- </div>
16
-
17
- <div class="col-2 last-feature">
18
- <img src="<?php echo "{$image_dir}/welcome-screenshot.jpg"; ?>" alt="<?php _e( 'Welcome Screenshot', 'easingslider' ); ?>" class="welcome-screenshot">
19
- </div>
20
- </div>
21
- </div>
22
- <hr>
23
-
24
- <div class="changelog">
25
- <h3><?php _e( 'Displaying A Slider', 'easingslider' ); ?></h3>
26
-
27
- <div class="feature-section col three-col">
28
- <div class="col-1">
29
- <img src="<?php echo "{$image_dir}/shortcode-screenshot.jpg"; ?>" alt="<?php _e( 'Shortcode Screenshot', 'easingslider' ); ?>" class="shortcode-screenshot">
30
- <h4><?php _e( 'In a post', 'easingslider' ); ?></h4>
31
- <p>Use the "Add Slider" button within the post editor to add a slider to a post or page. For reference, the shortcode can be found below. Be sure to replace the numeric ID (1) with the ID of the slider you wish to show.</p>
32
- <code>[easingslider id="1"]</code>
33
- </div>
34
-
35
- <div class="col-2">
36
- <img src="<?php echo "{$image_dir}/function-screenshot.jpg"; ?>" alt="<?php _e( 'PHP Function Screenshot', 'easingslider' ); ?>" class="function-screenshot">
37
- <h4>PHP Function</h4>
38
- <p>You can also display a slider inside a theme file using the PHP function below. Again, be sure to replace the numeric ID (1) with the desired slider ID.</p>
39
- <code>&lt;?php if ( function_exists( 'easingslider' ) ) { easingslider( 1 ); } ?&gt;</code>
40
- </div>
41
- <div class="col-3 last-feature">
42
- <img src="<?php echo "{$image_dir}/widget-screenshot.jpg"; ?>" alt="<?php _e( 'Widget Screenshot', 'easingslider' ); ?>" class="widget-screenshot">
43
- <h4>Widget</h4>
44
- <p>Easing Slider provides a widget that you can place in any widgetized area of your site and select exactly which form you would like displayed in that space.</p>
45
- </div>
46
- </div>
47
- </div>
48
- <hr>
49
-
50
- <div class="changelog">
51
- <h3><?php _e( 'Need help?', 'easingslider' ); ?></h3>
52
-
53
- <div class="feature-section col two-col">
54
- <div class="col-1">
55
- <h4><?php _e( 'Helpful Documentation', 'easingslider' ); ?></h4>
56
- <p><?php printf( __( 'We have documentation available covering everything from <a href="%s">Getting Started</a> to our <a href="%s">Developer API</a>. New documents and tutorials are added daily.', 'easingslider' ), 'http://easingslider.com/docs/installation', 'http://easingslider.com/docs/developer-api' ); ?></p>
57
- </div>
58
-
59
- <div class="col-2 last-feature">
60
- <h4><?php _e( 'Awesome Support', 'easingslider' ); ?></h4>
61
- <p><?php printf( __( 'We work hard to ensure every user gets the best support possible. If you\'ve encountered a problem or have a question, don\'t hesitate to <a href="%s">contact us</a>.', 'easingslider' ), 'http://easingslider.com/support' ); ?></p>
62
- </div>
63
- </div>
64
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -1,36 +1,49 @@
1
  === Easing Slider ===
2
  Homepage: http://easingslider.com
3
  Contributors: MatthewRuddy
4
- Tags: slideshow, slider, slides, slide, gallery, images, image, responsive, mobile, jquery, javascript, featured, content
5
- Requires at least: 4.0
6
- Tested up to: 4.2
7
- Stable tag: 2.2.1.1
8
 
9
- Easing Slider is an easy to use slider plugin. Simple and lightweight, is makes creating beautiful WordPress sliders a breeze.
10
 
11
  == Description ==
12
 
13
- Easing Slider is an extremely easy to use slider plugin for WordPress. It is built to be lightweight and simple, enabling you to create beautiful sliders quickly and efficiently. It comes with many great features, some of which include:
14
 
15
- * Fully responsive & mobile ready
16
- * Bulk image uploading, integrated with new WordPress Media Library
17
- * CSS3 transitions for ultra smooth transitions
18
- * Navigation arrows & pagination
19
- * Preloading functionality on page load
20
- * A visual editor for customizing basic styling
21
- * Developer friendly with built-in Javascript events
22
- * Dozens of extensions that greatly enhance plugin functionality
23
- * Lots of actions & filters for custom functionality
24
 
25
- <strong>Easing Slider has many great extensions that can vastly enhance the plugin's functionality. <a href="http://easingslider.com/extensions">Browse them all here</a>.</strong>
26
 
27
- Throughly tested on iPhone, iPad and multiple Android devices, Easing Slider is the perfect solution for mobile sliders. We've used CSS3 animation to ensure ultra smooth transitions on supported devices, with graceful fallbacks for older browsers.
28
 
29
- We've also integrated the new WordPress Media Library workflow to provide a better media management experience. Similar to the Media Library, the learning curve and minimal and the admin interface feels instantly recognisable. Bulk uploading images to your slider is now easy, requiring just a few clicks.
 
 
 
 
 
 
 
30
 
31
- Last but not least, we've left plenty of opportunity for custom plugin modifications using the WordPress Action & Filter APIs. You can completely create your own external functionality, or purchase <a href="http://easingslider.com/extensions">one of our extensions</a> to avail of pre-built additional features.
 
32
 
33
- <strong>Follow & contribute to this plugin on <a href="https://github.com/easingslider/easing-slider">Github</a>.</strong>
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  == Installation ==
36
 
@@ -75,6 +88,9 @@ This is easy. When editing a slider in the "All Sliders" admin area, simply clic
75
 
76
  == Changelog ==
77
 
 
 
 
78
  = 2.2.1.1 =
79
  * Fixed “Maximum call stack exceeded” bug encountered when displaying multiple sliders on a single page.
80
 
1
  === Easing Slider ===
2
  Homepage: http://easingslider.com
3
  Contributors: MatthewRuddy
4
+ Tags: slider, wordpress slider, carousel, image slider, responsive slider, slide, slider, slideshow, wordpress slideshow, youtube slider, photo slider, banner rotator, best slider, content slider, fullwidth slider, gallery, hardware accelerate, mobile slider,post slider, swipe, touch slider, page slider, slider plugin, slider shortcode
5
+ Requires at least: 4.5
6
+ Tested up to: 4.6
7
+ Stable tag: 3.0.0
8
 
9
+ The easiest way to create sliders with WordPress.
10
 
11
  == Description ==
12
 
13
+ Creating sliders with WordPress has always been a tricky business. Similiar plugins try to provide a solution but none really hit the mark. Easing Slider aims to fix that. This plugin focuses on achieving it's core purpose - to create and manage sliders with ease. It aims to keep slider creation simple, require little to no learning curve, and fit into the WordPress admin area like it was included from the start.
14
 
15
+ Put simply, Easing Slider makes creating sliders simple by providing just the features you need.
 
 
 
 
 
 
 
 
16
 
17
+ > Need additionals features? Easing Slider is fully flexible and can be enhanced with add-ons available to license holders only. Want to gain access? <a href="http://easingslider.com/#product-pricing" target="_blank">See Pricing</a>.
18
 
19
+ Some of the best Easing Slider features include:
20
 
21
+ #### Primary Features:
22
+ * Responsive & ready for all devices
23
+ * Seamless integration with the WordPress admin area
24
+ * Full WordPress Media Library integration
25
+ * Smooth transitions thanks to hardware acceleration
26
+ * Professional & reliable code by experienced PHP developers
27
+ * Lazy Loading for extremely fast page loading times
28
+ * Lots of add-ons to enhance functionality greatly (<a href="http://easingslider.com/addons" target="_blank">See our Website</a>)
29
 
30
+ #### Support
31
+ Need help & support? No problems. If you ever run into any trouble, don't hesitate to <a href="http://easingslider.com/support" target="_blank">Contact Us</a>.
32
 
33
+ #### Add-ons
34
+ Easing Slider is highly focused to ensure a solid user experience. To ensure this, we offer our additional features as installable add-ons. This ensures that you're using only the features you require, with nothing else to pollute your product experience.
35
+
36
+ Just some of the functionality offered:
37
+ * **Simple Captions** - Add captions to your slides with minimal effort!
38
+ * **Posts Feed** - Source slides from WordPress posts, pages, or a custom post type.
39
+ * **Thumbnails** - Use thumbnails as for slider pagination, instead of icons.
40
+ * **Video Slides** - Add videos to your sliders from YouTube, Vimeo or Wistia.
41
+ * **Carousel** - Turn your slider(s) into a carousel, showing multiple slides at once.
42
+ * **Lightbox** - Link images to a jQuery Lightbox
43
+ * **External Images** -
44
+
45
+ #### Embracing Open Source
46
+ Easing Slider is fully open source. We welcome all contributions, issues and criticism. Please don't hesitate to follow & contribute through Github. You can find our repository <a href="https://github.com/easingslider/easing-slider">here</a>.
47
 
48
  == Installation ==
49
 
88
 
89
  == Changelog ==
90
 
91
+ = 3.0.0 =
92
+ * A complete internal rebuild, now fully compatible with current versions of WordPress and those coming in the future. Marks the start of a new product direction for Easing Slider, and a renewed committment to continued development!
93
+
94
  = 2.2.1.1 =
95
  * Fixed “Maximum call stack exceeded” bug encountered when displaying multiple sliders on a single page.
96
 
resources/assets/css/admin.css ADDED
@@ -0,0 +1,791 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Global
2
+ -------------------------------------------------------------- */
3
+ .clearfix {
4
+ *zoom: 1;
5
+ }
6
+
7
+ .clearfix::before, .clearfix::after {
8
+ display: table;
9
+ content: '';
10
+ line-height: 0;
11
+ }
12
+
13
+ .clearfix::after {
14
+ clear: both;
15
+ }
16
+
17
+ .hide {
18
+ display: none !important;
19
+ }
20
+
21
+ .updated.notice {
22
+ border-color: #ffba00 !important;
23
+ }
24
+
25
+ .message.is-dismissable {
26
+ position: relative;
27
+ }
28
+
29
+ .field.half {
30
+ width: 45% !important;
31
+ }
32
+
33
+ .field.half:first-child {
34
+ margin-right: 5% !important;
35
+ }
36
+
37
+ .description {
38
+ font-size: 11px !important;
39
+ font-style: italic !important;
40
+ display: block !important;
41
+ color: #777 !important;
42
+ padding: 5px 0 !important;
43
+ }
44
+
45
+ .thumbnail-dashicon {
46
+ font-size: 15px;
47
+ height: 15px;
48
+ width: 15px;
49
+ margin-top: 1px;
50
+ margin-right: 2px;
51
+ }
52
+
53
+ /* Slider Editor
54
+ -------------------------------------------------------------- */
55
+ .wp-list-table .column-ID {
56
+ width: 4em;
57
+ }
58
+
59
+ .wp-list-table .column-post_title {
60
+ width: 35%;
61
+ }
62
+
63
+ .wp-list-table .column-template_function {
64
+ white-space: nowrap;
65
+ overflow: hidden;
66
+ text-overflow: ellipsis;
67
+ }
68
+
69
+ .wp-list-table td.post_title strong {
70
+ display: block;
71
+ margin-bottom: 0.2em;
72
+ font-size: 14px;
73
+ }
74
+
75
+ .wp-list-table .column-shortcode input[type="text"],
76
+ .wp-list-table .column-template_function input[type="text"] {
77
+ width: 100%;
78
+ }
79
+
80
+ .thumbnail .action .details-url {
81
+ width: 100%;
82
+ max-width: 700px;
83
+ }
84
+
85
+ .attachment-info .settings {
86
+ border-bottom-width: 0 !important;
87
+ }
88
+
89
+ .attachment-info .settings h3 {
90
+ margin: 10px 0;
91
+ position: relative;
92
+ font-weight: bold;
93
+ text-transform: uppercase;
94
+ font-size: 12px;
95
+ color: #666;
96
+ }
97
+
98
+ .attachment-info .setting .link-options {
99
+ width: 65%;
100
+ float: right;
101
+ margin: 1px;
102
+ }
103
+
104
+ .attachment-info .setting .link-options input[type="text"] {
105
+ width: 98%;
106
+ float: none;
107
+ margin: 5px 0 0 0;
108
+ }
109
+
110
+ .attachment-info .setting .link-options label {
111
+ margin-top: 5px;
112
+ }
113
+
114
+ .attachment-info .setting .link-options input[type="checkbox"] {
115
+ margin: -1px 5px 0 0 !important;
116
+ }
117
+
118
+ .attachment-info .column-settings h3.no-border {
119
+ border-top-width: 0;
120
+ padding-top: 0;
121
+ }
122
+
123
+ .edit-slide-frame select.attachment-filters {
124
+ max-width: 95%;
125
+ }
126
+
127
+ .edit-slide-frame .description {
128
+ margin-top: 10px !important;
129
+ }
130
+
131
+ .edit-slide-frame .media-embed .thumbnail {
132
+ max-height: none;
133
+ max-width: none;
134
+ }
135
+
136
+ .edit-slide-frame .media-embed .thumbnail img {
137
+ max-height: none;
138
+ max-width: 1000px;
139
+ width: 100%;
140
+ }
141
+
142
+ .media-modal .media-modal-close,
143
+ .edit-slide-frame .edit-media-header .left,
144
+ .edit-slide-frame .edit-media-header .right {
145
+ -webkit-transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
146
+ -moz-transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
147
+ -ms-transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
148
+ -o-transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
149
+ transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
150
+ cursor: pointer;
151
+ color: #777;
152
+ background-color: transparent;
153
+ height: 50px;
154
+ width: 50px;
155
+ padding: 0;
156
+ position: absolute;
157
+ text-align: center;
158
+ border: 0;
159
+ border-left: 1px solid #ddd;
160
+ }
161
+
162
+ .media-modal .media-modal-close {
163
+ top: 0;
164
+ right: 0;
165
+ }
166
+
167
+ .media-modal .media-modal-close.no-border,
168
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close {
169
+ border-width: 0;
170
+ }
171
+
172
+ .media-modal .media-modal-close.no-border:focus,
173
+ .media-modal .media-modal-close.no-border:hover,
174
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close:focus,
175
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close:hover {
176
+ background: transparent;
177
+ }
178
+
179
+ .media-modal .media-modal-close.no-border:focus .media-modal-icon:before,
180
+ .media-modal .media-modal-close.no-border:hover .media-modal-icon:before,
181
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close:focus .media-modal-icon:before,
182
+ div[id*="__wp-uploader-id"] .media-modal .media-modal-close:hover .media-modal-icon:before {
183
+ color: #0073aa;
184
+ }
185
+
186
+ .media-modal .media-modal-close .media-modal-icon:before {
187
+ content: '\f335';
188
+ font-size: 22px;
189
+ }
190
+
191
+ .media-modal .media-modal-close .media-modal-icon {
192
+ margin: 14px;
193
+ width: 22px;
194
+ }
195
+
196
+ .edit-slide-frame .edit-media-header .left {
197
+ right: 102px;
198
+ }
199
+
200
+ .edit-slide-frame .edit-media-header .right {
201
+ right: 51px;
202
+ }
203
+
204
+ .edit-slide-frame .edit-media-header .right:before,
205
+ .edit-slide-frame .edit-media-header .left:before {
206
+ font: normal 20px/50px 'dashicons' !important;
207
+ display: inline;
208
+ font-weight: 300;
209
+ }
210
+
211
+ .media-modal .media-modal-close:hover,
212
+ .media-modal .media-modal-close:focus,
213
+ .edit-slide-frame .edit-media-header .left:hover,
214
+ .edit-slide-frame .edit-media-header .right:hover,
215
+ .edit-slide-frame .edit-media-header .left:focus,
216
+ .edit-slide-frame .edit-media-header .right:focus {
217
+ background: #ddd;
218
+ border-color: #ccc;
219
+ color: #000;
220
+ outline: none;
221
+ }
222
+
223
+ .media-modal .media-modal-close:focus .media-modal-icon:before,
224
+ .media-modal .media-modal-close:hover .media-modal-icon:before {
225
+ color: #000;
226
+ }
227
+
228
+ .edit-slide-frame .edit-media-header .left:before,
229
+ .rtl .edit-slide-frame .edit-media-header .right:before {
230
+ content: '\f341';
231
+ }
232
+
233
+ .edit-slide-frame .edit-media-header .right:before,
234
+ .rtl .edit-slide-frame .edit-media-header .left:before {
235
+ content: '\f345';
236
+ }
237
+
238
+ .edit-slide-frame .edit-media-header .left.disabled,
239
+ .edit-slide-frame .edit-media-header .right.disabled,
240
+ .edit-slide-frame .edit-media-header .left.disabled:hover,
241
+ .edit-slide-frame .edit-media-header .right.disabled:hover {
242
+ color: #ccc;
243
+ background: inherit;
244
+ cursor: default;
245
+ pointer-events: none;
246
+ }
247
+
248
+ .edit-slide-frame .media-frame-title {
249
+ -webkit-box-shadow: none !important;
250
+ -moz-box-shadow: none !important;
251
+ box-shadow: none !important;
252
+ left: 0;
253
+ right: 150px; /* leave space for prev/next/close */
254
+ }
255
+
256
+ .edit-slide-frame .media-frame-content {
257
+ -webkit-box-shadow: inset 0px 4px 4px -4px rgba(0, 0, 0, 0.1);
258
+ -moz-box-shadow: inset 0px 4px 4px -4px rgba(0, 0, 0, 0.1);
259
+ box-shadow: inset 0px 4px 4px -4px rgba(0, 0, 0, 0.1);
260
+ }
261
+
262
+ .toolbar-container .media-toolbar {
263
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
264
+ -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
265
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
266
+ border: 1px solid #e5e5e5;
267
+ margin-top: 10px;
268
+ margin-bottom: 15px;
269
+ position: relative;
270
+ height: auto;
271
+ }
272
+
273
+ .toolbar-container .media-toolbar .media-toolbar-primary,
274
+ .toolbar-container .media-toolbar .media-toolbar-secondary {
275
+ max-width: 50%;
276
+ min-width: 384px;
277
+ }
278
+
279
+ .toolbar-container .media-toolbar .media-toolbar-primary {
280
+ text-align: right;
281
+ }
282
+
283
+ .toolbar-container .media-toolbar .media-toolbar-secondary {
284
+ margin-bottom: 9px;
285
+ }
286
+
287
+ .toolbar-container .media-toolbar .media-button {
288
+ margin-top: 10px;
289
+ margin-bottom: 10px;
290
+ }
291
+
292
+ .toolbar-container .media-toolbar .randomize {
293
+ float: none;
294
+ margin-top: 10px;
295
+ margin-bottom: 10px;
296
+ line-height: 30px;
297
+ display: inline-block;
298
+ }
299
+
300
+ .toolbar-container .media-toolbar .randomize input[type="checkbox"] {
301
+ margin-top: -2px;
302
+ margin-right: 8px;
303
+ }
304
+
305
+ .toolbar-container .media-toolbar .media-button {
306
+ float: none;
307
+ }
308
+
309
+ .toolbar-container .title-form {
310
+ float: left;
311
+ margin-top: 9px;
312
+ }
313
+
314
+ .toolbar-container .title-form .media-button {
315
+ margin-top: 1px;
316
+ margin-left: 0;
317
+ }
318
+
319
+ .toolbar-container .title-form label {
320
+ vertical-align: top;
321
+ font-weight: bold;
322
+ line-height: 32px;
323
+ margin: 0 5px 0 0;
324
+ }
325
+
326
+ .toolbar-container .title-form input[type="text"] {
327
+ margin: 0;
328
+ padding: 3px 5px;
329
+ width: 280px;
330
+ font-size: 16px;
331
+ font-weight: 300;
332
+ line-height: 1.5;
333
+ }
334
+
335
+ .main-container {
336
+ margin-right: 300px;
337
+ }
338
+
339
+ .slides-container {
340
+ width: 100%;
341
+ float: left;
342
+ }
343
+
344
+ .sidebar-container {
345
+ float: right;
346
+ margin-right: -300px;
347
+ width: 280px;
348
+ }
349
+
350
+ .settings-container .banners a {
351
+ display: block;
352
+ margin-bottom: 15px;
353
+ }
354
+
355
+ .settings-container .widgets-holder-wrap {
356
+ margin-top: 0;
357
+ margin-bottom: 10px;
358
+ }
359
+
360
+ .settings-container .sidebar-name {
361
+ border-bottom: 1px solid #eee;
362
+ }
363
+
364
+ .settings-container .sidebar-name h3 {
365
+ padding: 15px;
366
+ }
367
+
368
+ .settings-container .sidebar-name-arrow:before {
369
+ top: 4px !important;
370
+ padding: 14px !important;
371
+ }
372
+
373
+ .settings-container.closed .sidebar-name {
374
+ border-width: 0;
375
+ }
376
+
377
+ .settings-container .sidebar-content {
378
+ border-width: 0 1px 1px;
379
+ border-style: none solid solid;
380
+ border-color: #fff;
381
+ -webkit-border-bottom-right-radius: 3px;
382
+ -webkit-border-bottom-left-radius: 3px;
383
+ border-bottom-right-radius: 3px;
384
+ border-bottom-left-radius: 3px;
385
+ padding: 10px 15px;
386
+ min-height: 20px;
387
+ }
388
+
389
+ .settings-container .sidebar-content .divider {
390
+ margin-bottom: 0;
391
+ }
392
+
393
+ .settings-container .sidebar-content .field,
394
+ .settings-container .sidebar-content .radio {
395
+ width: 100%;
396
+ margin: 1em 0;
397
+ }
398
+
399
+ .settings-container .sidebar-content .field span {
400
+ font-weight: bold;
401
+ display: block;
402
+ }
403
+
404
+ .settings-container .sidebar-content .field {
405
+ float: left;
406
+ }
407
+
408
+ .settings-container .sidebar-content .field-extra {
409
+ margin-top: 0;
410
+ }
411
+
412
+ .settings-container .sidebar-content .field select,
413
+ .settings-container .sidebar-content .field input[type="text"],
414
+ .settings-container .sidebar-content .field input[type="number"] {
415
+ width: 90%;
416
+ }
417
+
418
+ .settings-container .sidebar-content .field input[type="checkbox"] {
419
+ margin-right: 4px;
420
+ }
421
+
422
+ .settings-container .sidebar-content .radio > span {
423
+ font-weight: bold;
424
+ float: left;
425
+ }
426
+
427
+ .settings-container .sidebar-content .radio .buttons {
428
+ float: right;
429
+ }
430
+
431
+ .settings-container .sidebar-content .radio .buttons label {
432
+ margin-right: 10px;
433
+ }
434
+
435
+ .settings-container .sidebar-content .radio .buttons input {
436
+ margin-top: 0;
437
+ margin-right: 2px;
438
+ }
439
+
440
+ .settings-container .sidebar-content .show-advanced-options {
441
+ margin: 15px 0;
442
+ font-weight: bold;
443
+ display: block;
444
+ }
445
+
446
+ .settings-container .sidebar-content .manage-slides-buttons .dashicons-plus {
447
+ line-height: 28px;
448
+ }
449
+
450
+ .settings-container .sidebar-content .manage-slides-buttons .dashicons-trash {
451
+ line-height: 27px;
452
+ }
453
+
454
+ .settings-container .sidebar-content .misc-pub-section {
455
+ padding-left: 0;
456
+ padding-right: 0;
457
+ }
458
+
459
+ .settings-container #major-publishing-actions .submitdelete {
460
+ text-decoration: none;
461
+ padding: 1px 2px;
462
+ color: #a00;
463
+ }
464
+
465
+ .settings-container #major-publishing-actions .submitdelete:hover {
466
+ color: #f00;
467
+ text-decoration: none;
468
+ border: none;
469
+ }
470
+
471
+ #slides-browser .ui-sortable {
472
+ min-height: 300px;
473
+ }
474
+
475
+ #slides-browser .spinner {
476
+ float: left;
477
+ display: inline;
478
+ }
479
+
480
+ #slides-browser .attachment .toolbar {
481
+ display: none;
482
+ text-align: left;
483
+ position: absolute;
484
+ top: 0;
485
+ left: 0;
486
+ }
487
+
488
+ #slides-browser .attachment:hover .toolbar {
489
+ display: block;
490
+ }
491
+
492
+ #slides-browser .attachment .toolbar i {
493
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
494
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
495
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
496
+ position: relative;
497
+ margin-top: 7px;
498
+ margin-left: 7px;
499
+ padding: 2px;
500
+ font-size: 30px;
501
+ height: 30px;
502
+ width: 30px;
503
+ background: #000;
504
+ background: rgba(0, 0, 0, 0.9);
505
+ cursor: pointer;
506
+ z-index: 9999;
507
+ color: #fff;
508
+ }
509
+
510
+ #slides-browser .attachment .toolbar i:hover {
511
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
512
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
513
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
514
+ background-color: #000;
515
+ color: #2ea2cc;
516
+ }
517
+
518
+ #slides-browser .attachment .check div {
519
+ background-position: 21px 0;
520
+ }
521
+
522
+ #slides-browser .attachment.selected .check div {
523
+ background-position: -21px 0;
524
+ }
525
+
526
+ #slides-browser .attachment.selected .check:hover div {
527
+ background-position: -60px 0;
528
+ }
529
+
530
+ #slides-browser .thumbnail img {
531
+ width: 100%;
532
+ }
533
+
534
+ #slides-browser .thumbnail img.icon {
535
+ width: auto;
536
+ }
537
+
538
+ #slides-browser .thumbnail:hover .delete-button {
539
+ opacity: 1;
540
+ }
541
+
542
+ /* Settings
543
+ -------------------------------------------------------------- */
544
+ .form-table label span {
545
+ margin-right: 15px;
546
+ }
547
+
548
+ .valid-license {
549
+ position: relative;
550
+ }
551
+
552
+ .valid-license:after {
553
+ content: "\f147";
554
+ font-family: "Dashicons";
555
+ position: absolute;
556
+ top: 0;
557
+ bottom: 0;
558
+ right: 10px;
559
+ color: #468847;
560
+ font-size: 18px;
561
+ }
562
+
563
+ /* License Entry
564
+ -------------------------------------------------------------- */
565
+ .license-entry {
566
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);
567
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);
568
+ border-left: 4px solid #fff;
569
+ background: #fff;
570
+ padding: 16px 10px;
571
+ margin-bottom: 15px;
572
+ }
573
+
574
+ .license-entry.license-required {
575
+ border-left-color: #ffba00;
576
+ }
577
+
578
+ .license-entry.license-valid {
579
+ border-left-color: #46b450;
580
+ }
581
+
582
+ .license-entry p {
583
+ margin-top: 0 !important;
584
+ }
585
+
586
+ .license-entry #license-key {
587
+ min-width: 300px;
588
+ margin-right: 5px;
589
+ }
590
+
591
+ .license-entry #masked-key {
592
+ line-height: 28px;
593
+ margin-right: 5px;
594
+ }
595
+
596
+ /* Addons
597
+ -------------------------------------------------------------- */
598
+ .addon {
599
+ background: #fff;
600
+ border: 1px solid #ccc;
601
+ margin: 0 20px 20px 0;
602
+ padding: 15px;
603
+ float: left;
604
+ width: 300px;
605
+ height: 410px;
606
+ position: relative;
607
+ }
608
+
609
+ .addon .addon-thumbnail {
610
+ display: block;
611
+ }
612
+
613
+ .addon .addon-thumbnail img {
614
+ max-width: 100%;
615
+ }
616
+
617
+ .addon .action-error {
618
+ line-height: 28px;
619
+ margin: 10px 0;
620
+ display: block;
621
+ }
622
+
623
+ .addon .addon-action {
624
+ display: block;
625
+ /*margin: -16px -16px 15px -16px;*/
626
+ }
627
+
628
+ .addon .addon-image {
629
+ max-width: 100%;
630
+ height: auto;
631
+ }
632
+
633
+ .addon .addon-status {
634
+ position: absolute;
635
+ bottom: 15px;
636
+ left: 15px;
637
+ right: 15px;
638
+ padding: 6px 10px;
639
+ background: #eaeaea;
640
+ border-width: 1px;
641
+ border-style: solid;
642
+ border-color: #dadada;
643
+ }
644
+
645
+ .addon .addon-status.no-license {
646
+ color: #a94442;
647
+ background: #f2dede;
648
+ border-color: #dca7a7;
649
+ }
650
+
651
+ .addon .addon-status.upgrade-license {
652
+ color: #8a6d3b;
653
+ background: #fcf8e3;
654
+ border-color: #f5e79e;
655
+ }
656
+
657
+ .addon .addon-status.is-inactive {
658
+ color: #31708f;
659
+ background: #d9edf7;
660
+ border-color: #9acfea;
661
+ }
662
+
663
+ .addon .addon-status.is-active {
664
+ color: #3c763d;
665
+ background: #dff0d8;
666
+ border-color: #b2dba1;
667
+ }
668
+
669
+ .addon .addon-status span {
670
+ line-height: 28px;
671
+ }
672
+
673
+ .addon .addon-status .button-primary {
674
+ float: right;
675
+ }
676
+
677
+ .addon .addon-status .upgrade-link {
678
+ display: block;
679
+ }
680
+
681
+ /* Upgrade Info
682
+ -------------------------------------------------------------- */
683
+ .upgrade-info .upgrade-info-title {
684
+ font-size: 24px;
685
+ }
686
+
687
+ .upgrade-info .upgrade-info-list li {
688
+ display: inline-block;
689
+ margin-right: 20px;
690
+ }
691
+
692
+ /* Media Queries
693
+ -------------------------------------------------------------- */
694
+ @media only screen and (max-width: 1040px) {
695
+ .toolbar-container .media-toolbar .media-toolbar-primary,
696
+ .toolbar-container .media-toolbar .media-toolbar-secondary {
697
+ max-width: 100%;
698
+ float: none;
699
+ }
700
+
701
+ .toolbar-container .media-toolbar .media-toolbar-primary {
702
+ text-align: left;
703
+ }
704
+ }
705
+
706
+ @media only screen and (max-width: 900px) {
707
+ .attachment-info .setting .link-options {
708
+ width: 100%;
709
+ float: none;
710
+ }
711
+ }
712
+
713
+ @media only screen and (max-width: 782px) {
714
+ .wp-list-table .column-post_title {
715
+ width: 75%;
716
+ }
717
+
718
+ .wp-list-table .column-post_author,
719
+ .wp-list-table .column-post_date,
720
+ .wp-list-table .column-shortcode,
721
+ .wp-list-table .column-template_function {
722
+ display: none;
723
+ }
724
+ }
725
+
726
+ @media only screen and (max-width: 640px) {
727
+ .media-modal {
728
+ left: 0 !important;
729
+ right: 0 !important;
730
+ }
731
+
732
+ .media-modal select,
733
+ .media-modal textarea,
734
+ .media-modal input[type="url"],
735
+ .media-modal input[type="text"] {
736
+ font-size: 16px;
737
+ padding: 6px 10px;
738
+ }
739
+
740
+ .attachment-info .media-modal {
741
+ left: 0 !important;
742
+ right: 0 !important;
743
+ }
744
+
745
+ .attachment-info .setting .link-options {
746
+ width: 100%;
747
+ float: none;
748
+ margin: 1px;
749
+ }
750
+
751
+ .attachment-info .setting .link-options label {
752
+ margin-top: 8px;
753
+ }
754
+
755
+ .toolbar-container .media-toolbar .media-toolbar-primary {
756
+ margin-bottom: 15px;
757
+ }
758
+
759
+ .toolbar-container .media-toolbar .media-toolbar-secondary {
760
+ margin-top: 10px;
761
+ }
762
+
763
+ .toolbar-container .media-toolbar .randomize {
764
+ display: block;
765
+ float: none;
766
+ }
767
+
768
+ .toolbar-container .media-toolbar .media-button {
769
+ float: none;
770
+ margin: 0 10px 10px 0;
771
+ }
772
+
773
+ .main-container {
774
+ margin-right: 0;
775
+ }
776
+
777
+ .slides-container {
778
+ float: none;
779
+ }
780
+
781
+ #slides-browser .ui-sortable {
782
+ min-height: 100px;
783
+ }
784
+
785
+ .settings-container {
786
+ float: none;
787
+ margin-top: 20px;
788
+ margin-right: 0;
789
+ width: 100%;
790
+ }
791
+ }
resources/assets/css/public.css ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Slides
2
+ -------------------------------------------------------------- */
3
+ .easingslider-slide {
4
+ background-color: #fff;
5
+ }
6
+
7
+ /* Images
8
+ -------------------------------------------------------------- */
9
+ .easingslider-image {
10
+ margin-top: 0 !important;
11
+ margin-bottom: 0 !important;
12
+ padding: 0 !important;
13
+ }
14
+
15
+ /* Links
16
+ -------------------------------------------------------------- */
17
+ .easingslider-link {
18
+ display: block;
19
+ }
20
+
21
+ /* Lazy Loading
22
+ -------------------------------------------------------------- */
23
+ .easingslider-item.loading {
24
+ background-image: url(../images/loading.gif);
25
+ background-repeat: no-repeat;
26
+ background-position: center center;
27
+ background-color: #fff;
28
+ }
29
+
30
+ /* Arrows
31
+ -------------------------------------------------------------- */
32
+ .easingslider-prev,
33
+ .easingslider-next {
34
+ position: absolute;
35
+ top: 50%;
36
+ width: 30px;
37
+ height: 30px;
38
+ margin-top: -15px;
39
+ background-repeat: no-repeat;
40
+ z-index: 40;
41
+ cursor: pointer;
42
+ }
43
+
44
+ .easingslider-next {
45
+ background-image: url(../images/nav-arrow-next.png);
46
+ background-position: top right;
47
+ }
48
+
49
+ .easingslider-prev {
50
+ background-image: url(../images/nav-arrow-prev.png);
51
+ background-position: top left;
52
+ }
53
+
54
+ .easingslider-arrows-inside .easingslider-next {
55
+ right: 10px;
56
+ }
57
+
58
+ .easingslider-arrows-inside .easingslider-prev {
59
+ left: 10px;
60
+ }
61
+
62
+ .easingslider-arrows-outside .easingslider-next {
63
+ right: -40px;
64
+ padding-left: 20px;
65
+ }
66
+
67
+ .easingslider-arrows-outside .easingslider-prev {
68
+ left: -40px;
69
+ padding-right: 20px;
70
+ }
71
+
72
+ .easingslider-arrows-hover .easingslider-prev,
73
+ .easingslider-arrows-hover .easingslider-next {
74
+ opacity: 0;
75
+ -webkit-transition: opacity 0.3s ease, -webkit-transform 0.1s ease-in;
76
+ -moz-transition: opacity 0.3s ease, -moz-transform 0.1s ease-in;
77
+ -ms-transition: opacity 0.3s ease, -ms-transform 0.1s ease-in;
78
+ -o-transition: opacity 0.3s ease, -o-transform 0.1s ease-in;
79
+ transition: opacity 0.3s ease, transform 0.1s ease-in;
80
+ }
81
+
82
+ .easingslider-arrows-hover .easingslider-prev {
83
+ -webkit-transform: translate3d(-10px, 0, 0);
84
+ -moz-transform: translate3d(-10px, 0, 0);
85
+ -ms-transform: translate3d(-10px, 0, 0);
86
+ -o-transform: translate3d(-10px, 0, 0);
87
+ transform: translate3d(-10px, 0, 0);
88
+ }
89
+
90
+ .easingslider-arrows-hover .easingslider-next {
91
+ -webkit-transform: translate3d(10px, 0, 0);
92
+ -moz-transform: translate3d(10px, 0, 0);
93
+ -ms-transform: translate3d(10px, 0, 0);
94
+ -o-transform: translate3d(10px, 0, 0);
95
+ transform: translate3d(10px, 0, 0);
96
+ }
97
+
98
+ .easingslider-arrows-hover:hover .easingslider-prev,
99
+ .easingslider-arrows-hover:hover .easingslider-next {
100
+ opacity: 1;
101
+ -webkit-transform: translate3d(0, 0, 0);
102
+ -moz-transform: translate3d(0, 0, 0);
103
+ -ms-transform: translate3d(0, 0, 0);
104
+ -o-transform: translate3d(0, 0, 0);
105
+ transform: translate3d(0, 0, 0);
106
+ }
107
+
108
+ /* Pagination
109
+ -------------------------------------------------------------- */
110
+ .easingslider-pagination {
111
+ position: absolute;
112
+ height: 17px;
113
+ z-index: 40;
114
+ }
115
+
116
+ .easingslider-pagination .easingslider-page {
117
+ display: inline-block;
118
+ *display: inline; /** IE7 hack */
119
+ zoom: 1; /** IE7 hack */
120
+ }
121
+
122
+ .easingslider-pagination .easingslider-page span {
123
+ width: 15px;
124
+ height: 15px;
125
+ margin: 0 2px 0 0;
126
+ padding: 0;
127
+ background-image: url(../images/nav-icon-inactive.png);
128
+ background-repeat: no-repeat;
129
+ background-position: 0 0;
130
+ display: block;
131
+ z-index: 40;
132
+ cursor: pointer;
133
+ }
134
+
135
+ .easingslider-pagination .easingslider-page:last-child span {
136
+ margin-right: 0;
137
+ }
138
+
139
+ .easingslider-pagination .easingslider-page.active span {
140
+ background-image: url(../images/nav-icon-active.png);
141
+ }
142
+
143
+ .easingslider-pagination-inside.easingslider-pagination-bottom-left .easingslider-pagination {
144
+ bottom: 10px;
145
+ left: 10px;
146
+ }
147
+
148
+ .easingslider-pagination-inside.easingslider-pagination-bottom-right .easingslider-pagination {
149
+ bottom: 10px;
150
+ right: 10px;
151
+ }
152
+
153
+ .easingslider-pagination-inside.easingslider-pagination-bottom-center .easingslider-pagination {
154
+ bottom: 10px;
155
+ left: 0;
156
+ width: 100%;
157
+ text-align: center;
158
+ }
159
+
160
+ .easingslider-pagination-inside.easingslider-pagination-top-left .easingslider-pagination {
161
+ top: 10px;
162
+ left: 10px;
163
+ }
164
+
165
+ .easingslider-pagination-inside.easingslider-pagination-top-right .easingslider-pagination {
166
+ top: 10px;
167
+ right: 10px;
168
+ }
169
+
170
+ .easingslider-pagination-inside.easingslider-pagination-top-center .easingslider-pagination {
171
+ top: 10px;
172
+ left: 0;
173
+ right: 0;
174
+ width: 100%;
175
+ text-align: center;
176
+ }
177
+
178
+ .easingslider-pagination-outside.easingslider-pagination-bottom-left .easingslider-pagination {
179
+ bottom: -25px;
180
+ left: 0;
181
+ padding-top: 20px;
182
+ }
183
+
184
+ .easingslider-pagination-outside.easingslider-pagination-bottom-right .easingslider-pagination {
185
+ bottom: -25px;
186
+ right: 0;
187
+ padding-top: 20px;
188
+ }
189
+
190
+ .easingslider-pagination-outside.easingslider-pagination-bottom-center .easingslider-pagination {
191
+ bottom: -25px;
192
+ left: 0;
193
+ right: 0;
194
+ width: 100%;
195
+ text-align: center;
196
+ padding-top: 20px;
197
+ }
198
+
199
+ .easingslider-pagination-outside.easingslider-pagination-top-left .easingslider-pagination {
200
+ top: -25px;
201
+ left: 0;
202
+ padding-bottom: 20px;
203
+ }
204
+
205
+ .easingslider-pagination-outside.easingslider-pagination-top-right .easingslider-pagination {
206
+ top: -25px;
207
+ right: 0;
208
+ padding-bottom: 20px;
209
+ }
210
+
211
+ .easingslider-pagination-outside.easingslider-pagination-top-center .easingslider-pagination {
212
+ top: -25px;
213
+ left: 0;
214
+ width: 100%;
215
+ text-align: center;
216
+ padding-bottom: 20px;
217
+ }
218
+
219
+ .easingslider-pagination-hover .easingslider-pagination {
220
+ opacity: 0;
221
+ -webkit-transition: opacity 0.3s ease;
222
+ -moz-transition: opacity 0.3s ease;
223
+ -ms-transition: opacity 0.3s ease;
224
+ -o-transition: opacity 0.3s ease;
225
+ transition: opacity 0.3s ease;
226
+ }
227
+
228
+ .easingslider-pagination-hover:hover .easingslider-pagination {
229
+ opacity: 1;
230
+ }
resources/assets/images/easingslider-badge.jpg ADDED
Binary file
resources/assets/images/function-screenshot.jpg ADDED
Binary file
resources/assets/images/interface-screenshot.jpg ADDED
Binary file
resources/assets/images/list-screenshot.jpg ADDED
Binary file
resources/assets/images/loading.gif ADDED
Binary file
resources/assets/images/loading@2x.gif ADDED
Binary file
resources/assets/images/nav-arrow-next.png ADDED
Binary file
resources/assets/images/nav-arrow-next@2x.png ADDED
Binary file
resources/assets/images/nav-arrow-prev.png ADDED
Binary file
resources/assets/images/nav-arrow-prev@2x.png ADDED
Binary file
resources/assets/images/nav-icon-active.png ADDED
Binary file
resources/assets/images/nav-icon-active@2x.png ADDED
Binary file
resources/assets/images/nav-icon-inactive.png ADDED
Binary file
resources/assets/images/nav-icon-inactive@2x.png ADDED
Binary file
resources/assets/images/placeholder-pixel.png ADDED
Binary file
resources/assets/images/pro-bundle.png ADDED
Binary file
resources/assets/images/shadow.png ADDED
Binary file
resources/assets/images/shortcode-screenshot.jpg ADDED
Binary file
resources/assets/images/welcome-screenshot.jpg ADDED
Binary file
resources/assets/images/widget-screenshot.jpg ADDED
Binary file
resources/assets/js/admin.js ADDED
@@ -0,0 +1,2157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Namespace
3
+ */
4
+ window.EasingSlider = window.EasingSlider || {};
5
+ window.EasingSlider.Admin = window.EasingSlider.Admin || {};
6
+
7
+ // Add our components
8
+ _.extend(EasingSlider.Admin, {
9
+ model: {},
10
+ collection: {},
11
+ controller: {},
12
+ frame: {},
13
+ view: {},
14
+ toolbar: {},
15
+ router: {},
16
+ Router: {}
17
+ });
18
+
19
+ /**
20
+ * Defines the admin functionality
21
+ */
22
+ (function($) {
23
+
24
+ var Admin = window.EasingSlider.Admin;
25
+
26
+ /**
27
+ * Returns the appropriate "Slide" model
28
+ */
29
+ Admin.model.Slide = {
30
+
31
+ /**
32
+ * Get the appropriate model
33
+ */
34
+ get: function(attributes) {
35
+
36
+ if ( 'undefined' !== typeof Admin.model.Slide[attributes.type] ) {
37
+ return new Admin.model.Slide[attributes.type](attributes);
38
+ }
39
+
40
+ return new Admin.model.Slide.base(attributes);
41
+
42
+ }
43
+
44
+ };
45
+
46
+ /**
47
+ * Base Slide Model
48
+ */
49
+ Admin.model.Slide.base = Backbone.Model.extend();
50
+
51
+ /**
52
+ * "Image" Slide Model
53
+ */
54
+ Admin.model.Slide.image = Admin.model.Slide.base.extend({
55
+
56
+ /**
57
+ * Attachment
58
+ */
59
+ attachment: false,
60
+
61
+ /**
62
+ * Defaults
63
+ */
64
+ defaults: {
65
+ attachment_id: null,
66
+ type: 'image',
67
+ alt: '',
68
+ link: 'none',
69
+ linkUrl: '',
70
+ linkTargetBlank: false,
71
+ title: '',
72
+ url: null
73
+ }
74
+
75
+ });
76
+
77
+ /**
78
+ * Slides Collection
79
+ */
80
+ Admin.collection.Slides = Backbone.Collection.extend({
81
+
82
+ /**
83
+ * The models for this collection are polymorphic,
84
+ * so the model to add is determined by function.
85
+ *
86
+ * Don't be fooled, Admin.model.Slide.get is just a function (not a model).
87
+ */
88
+ model: Admin.model.Slide.get,
89
+
90
+ /**
91
+ * Constructor
92
+ */
93
+ initialize: function() {
94
+
95
+ // Bind our collection events
96
+ this.on('add', this._resetIDs, this);
97
+ this.on('remove', this._resetIDs, this);
98
+ this.on('reset', this._resetIDs, this);
99
+
100
+ },
101
+
102
+ /**
103
+ * Comparator
104
+ */
105
+ comparator: function(model) {
106
+
107
+ return model.get('id');
108
+
109
+ },
110
+
111
+ /**
112
+ * Resets the ID attribute on each model
113
+ */
114
+ _resetIDs: function() {
115
+
116
+ // Create a new collection. We need to do this to avoid issues with duplicate IDs.
117
+ var collection = new Backbone.Collection();
118
+
119
+ // Loop through each model and update the ID attribute. Then add it to our collection.
120
+ _.each(this.models, function(model, index) {
121
+ model.set({ id: index + 1 });
122
+
123
+ collection.add(model);
124
+ });
125
+
126
+ // Reset this collection with the models from our temporary collection
127
+ this.reset(collection.models, { silent: true });
128
+
129
+ },
130
+
131
+ /**
132
+ * Repositions a model to the specified index in the collection
133
+ */
134
+ reposition: function(model, index) {
135
+
136
+ // Remove the model
137
+ this.remove(model, { silent: true });
138
+
139
+ // Add the model at our desired index
140
+ this.add(model, { at: index, silent: true });
141
+
142
+ // Reset the IDs
143
+ this._resetIDs();
144
+
145
+ return this;
146
+
147
+ },
148
+
149
+ /**
150
+ * Syncs the models in this collection
151
+ */
152
+ sync: function() {
153
+
154
+ var collection = this,
155
+ ids = [];
156
+
157
+ // Loop through each model and get attachment IDs
158
+ _.each(this.models, function(model) {
159
+
160
+ // Check if the model has an attachment ID
161
+ if ( model.has('attachment_id') ) {
162
+ ids.push(model.get('attachment_id'));
163
+ }
164
+
165
+ }, this);
166
+
167
+ // Query the WordPress Media Library
168
+ var query = wp.media.query({
169
+ post__in: ids,
170
+ posts_per_page: -1
171
+ });
172
+
173
+ // Do the query
174
+ query.more().done(function() {
175
+ _.each(query.models, function(attachment) {
176
+
177
+ // Get models with a matching ID
178
+ var matches = collection.where({ attachment_id: attachment.get('id') });
179
+
180
+ // Loop through each match
181
+ _.each(matches, function(model) {
182
+
183
+ // Set the attachment object
184
+ model.attachment = attachment;
185
+
186
+ });
187
+
188
+ });
189
+
190
+ // Trigger a sync action
191
+ collection.trigger('sync:done');
192
+ });
193
+
194
+ return this;
195
+
196
+ }
197
+
198
+ });
199
+
200
+ /**
201
+ * Returns the appropriate "Add Slide" controller
202
+ */
203
+ Admin.controller.AddSlide = {
204
+
205
+ /**
206
+ * Get the appropriate controller
207
+ */
208
+ get: function(options) {
209
+
210
+ if ( 'undefined' !== typeof Admin.controller.AddSlide[options.type] ) {
211
+ return new Admin.controller.AddSlide[options.type](options);
212
+ }
213
+
214
+ return new Admin.controller.AddSlide.base(options);
215
+
216
+ }
217
+
218
+ };
219
+
220
+ /**
221
+ * Base "Add Slide" Controller
222
+ */
223
+ Admin.controller.AddSlide.base = wp.media.controller.State.extend({
224
+
225
+ /**
226
+ * Constructor
227
+ */
228
+ initialize: function() {
229
+
230
+ // Get the model
231
+ this.props = new Admin.model.Slide.get({
232
+ type: this.get('type')
233
+ });
234
+
235
+ }
236
+
237
+ });
238
+
239
+ /**
240
+ * Image "Add Slide" Controller
241
+ */
242
+ Admin.controller.AddSlide.image = wp.media.controller.Library.extend();
243
+
244
+ /**
245
+ * Returns the appropriate "Edit Slide" controller
246
+ */
247
+ Admin.controller.EditSlide = {
248
+
249
+ /**
250
+ * Get the appropriate controller
251
+ */
252
+ get: function(options) {
253
+
254
+ if ( 'undefined' !== typeof Admin.controller.EditSlide[options.type] ) {
255
+ return new Admin.controller.EditSlide[options.type](options);
256
+ }
257
+
258
+ return new Admin.controller.EditSlide.base(options);
259
+
260
+ }
261
+
262
+ };
263
+
264
+ /**
265
+ * Base "Edit Slide" Controller
266
+ */
267
+ Admin.controller.EditSlide.base = wp.media.controller.State.extend({
268
+
269
+ /**
270
+ * Defaults
271
+ */
272
+ defaults: _.defaults({
273
+ id: 'edit-slide',
274
+ title: _easingsliderAdminL10n.media_upload.title,
275
+ content: 'edit-slide',
276
+ menu: false,
277
+ router: false,
278
+ toolbar: 'edit-slide',
279
+ editing: false,
280
+ priority: 60
281
+ }, wp.media.controller.State.defaults )
282
+
283
+ });
284
+
285
+ /**
286
+ * Image "Edit Slide" Controller
287
+ */
288
+ Admin.controller.EditSlide.image = Admin.controller.EditSlide.base.extend();
289
+
290
+ /**
291
+ * "Add Slide" Frame
292
+ */
293
+ Admin.frame.AddSlide = wp.media.view.MediaFrame.Post.extend({
294
+
295
+ /**
296
+ * Constructor
297
+ */
298
+ initialize: function() {
299
+
300
+ // Alter defaults
301
+ _.defaults(this.options, {
302
+ multiple: true
303
+ });
304
+
305
+ // Call parent constructor
306
+ wp.media.view.MediaFrame.Post.prototype.initialize.apply(this, arguments);
307
+
308
+ },
309
+
310
+ /**
311
+ * Bind event handlers
312
+ */
313
+ bindHandlers: function() {
314
+
315
+ // Bind Handlers
316
+ this.on('close', this.updateRouter, this);
317
+ this.on('content:render:browse', this.removeSidebar, this);
318
+ this.on('toolbar:create:insert-slide', this.createToolbar, this);
319
+ this.on('toolbar:render:insert-slide', this.insertToolbar, this);
320
+
321
+ // Call parent
322
+ wp.media.view.MediaFrame.Post.prototype.bindHandlers.apply(this, arguments);
323
+
324
+ },
325
+
326
+ /**
327
+ * Render callback for the content region in the 'browse' mode.
328
+ */
329
+ browseContent: function(contentRegion) {
330
+
331
+ // Get the state
332
+ var state = this.state();
333
+
334
+ // Show the toolbar
335
+ this.$el.removeClass('hide-toolbar');
336
+
337
+ // Browse our library of attachments
338
+ contentRegion.view = new Admin.view.AddSlide.image({
339
+ controller: this,
340
+ collection: state.get('library'),
341
+ selection: state.get('selection'),
342
+ model: state,
343
+ sortable: state.get('sortable'),
344
+ search: state.get('searchable'),
345
+ filters: state.get('filterable'),
346
+ date: state.get('date'),
347
+ display: state.has('display') ? state.get('display') : state.get('displaySettings'),
348
+ dragInfo: state.get('dragInfo'),
349
+ idealColumnWidth: state.get('idealColumnWidth'),
350
+ suggestedWidth: state.get('suggestedWidth'),
351
+ suggestedHeight: state.get('suggestedHeight'),
352
+ AttachmentView: state.get('AttachmentView')
353
+ });
354
+
355
+ },
356
+
357
+ /**
358
+ * Removes the sidebar from the frame
359
+ */
360
+ removeSidebar: function(view) {
361
+
362
+ // Remove the sidebar
363
+ view.sidebar.remove('details');
364
+
365
+ // Hide sidebar altogether
366
+ view.$el.addClass('hide-sidebar');
367
+
368
+ },
369
+
370
+ /**
371
+ * Creates our states
372
+ */
373
+ createStates: function() {
374
+
375
+ // Add the default states
376
+ this.states.add([
377
+ new Admin.controller.AddSlide.image({
378
+ id: 'insert',
379
+ type: 'image',
380
+ title: _easingsliderAdminL10n.media_upload.image_from_media,
381
+ priority: 20,
382
+ toolbar: 'insert-slide',
383
+ filterable: false,
384
+ library: wp.media.query({ type: 'image' }),
385
+ multiple: true,
386
+ editable: true,
387
+ allowLocalEdits: true,
388
+ displaySettings: false,
389
+ displayUserSettings: true
390
+ })
391
+ ]);
392
+
393
+ },
394
+
395
+ /**
396
+ * We're overriding this method to prevent WordPress from adding iFrame states to our states.
397
+ * We don't want these, simple.
398
+ */
399
+ createIframeStates: function() {
400
+
401
+ return this;
402
+
403
+ },
404
+
405
+ /**
406
+ * Adds our "Insert into Slider" toolbar
407
+ */
408
+ insertToolbar: function(view) {
409
+
410
+ var controller = this;
411
+
412
+ // Add the toolbar to our provided view
413
+ view.set('insert-slide', {
414
+ style: 'primary',
415
+ priority: 80,
416
+ text: _easingsliderAdminL10n.media_upload.insert_into_slider,
417
+ requires: { selection: false },
418
+ click: function() {
419
+
420
+ // Close then trigger "insert", providing the selection
421
+ controller.close().trigger('insert', controller.getSelection()).reset();
422
+
423
+ }
424
+ });
425
+
426
+ },
427
+
428
+ /**
429
+ * Prepares & returns our selection for handoff to our view(s)
430
+ */
431
+ getSelection: function(selection) {
432
+
433
+ var collection = new wp.media.model.Selection(null, { multiple: true });
434
+
435
+ // Get the type & selection
436
+ var type = this.state().get('type'),
437
+ selection = this.state().get('selection');
438
+
439
+ // Loop through each selection
440
+ _.each(selection.models, function(model) {
441
+
442
+ // Create a new slide & set its type
443
+ var slide = new Admin.model.Slide.get({
444
+ type: type
445
+ });
446
+
447
+ // Handle attachments (attachments will have an ID attribute)
448
+ if ( model.get('id') ) {
449
+ slide.attachment = model;
450
+ slide.set({ attachment_id: model.get('id') }, { silent: true });
451
+ }
452
+ else {
453
+ slide.set(model, { silent: true });
454
+ }
455
+
456
+ // Add to the collection
457
+ collection.add(slide);
458
+
459
+ }, this);
460
+
461
+ return collection;
462
+
463
+ },
464
+
465
+ /**
466
+ * Updates the URL when the frame is closed
467
+ */
468
+ updateRouter: function() {
469
+
470
+ Admin.Router.navigate(_easingsliderAdminL10n.base_url);
471
+
472
+ }
473
+
474
+ });
475
+
476
+ /**
477
+ * Returns the appropriate "Edit Slide" controller
478
+ */
479
+ Admin.frame.EditSlide = {
480
+
481
+ /**
482
+ * Get the appropriate frame
483
+ */
484
+ get: function(options) {
485
+
486
+ if ( 'undefined' !== typeof Admin.frame.EditSlide[options.model.get('type')] ) {
487
+ return new Admin.frame.EditSlide[options.model.get('type')](options);
488
+ }
489
+
490
+ return new Admin.frame.EditSlide.base(options);
491
+
492
+ }
493
+
494
+ };
495
+
496
+ /**
497
+ * Base "Edit Slide" Frame
498
+ */
499
+ Admin.frame.EditSlide.base = wp.media.view.MediaFrame.Select.extend({
500
+
501
+ /**
502
+ * Classname
503
+ */
504
+ className: 'edit-slide-frame media-frame',
505
+
506
+ /**
507
+ * Template for this frame
508
+ */
509
+ template: wp.template('easingslider-edit-slide-frame'),
510
+
511
+ /**
512
+ * Events
513
+ */
514
+ events: _.defaults({
515
+ 'click .left': 'previousSlide',
516
+ 'click .right': 'nextSlide'
517
+ }, wp.media.view.MediaFrame.Select.prototype.events),
518
+
519
+ /**
520
+ * Constructor
521
+ */
522
+ initialize: function() {
523
+
524
+ // Set our options
525
+ this.options.state = 'edit-slide';
526
+ this.options.selection = new wp.media.model.Selection({}, { multiple: false });
527
+
528
+ // Call parent constructor
529
+ wp.media.view.MediaFrame.Select.prototype.initialize.apply(this, arguments);
530
+
531
+ },
532
+
533
+ /**
534
+ * Bind event handlers
535
+ */
536
+ bindHandlers: function() {
537
+
538
+ var frame = this;
539
+
540
+ // Bind events
541
+ this.on('close', this.updateRouter, this);
542
+ this.on('content:create:edit-slide', this.createView, this);
543
+ this.on('toolbar:render:edit-slide', this.createToolbar, this);
544
+
545
+ // Call parent
546
+ wp.media.view.MediaFrame.Select.prototype.bindHandlers.apply(this, arguments);
547
+
548
+ },
549
+
550
+ /**
551
+ * Creates the view
552
+ */
553
+ createView: function(options) {
554
+
555
+ // Initiate the view
556
+ options.view = new Admin.view.EditSlide.get({
557
+ type: this.model.get('type'),
558
+ model: this.model,
559
+ controller: this
560
+ });
561
+
562
+ },
563
+
564
+ /**
565
+ * Creates the toolbar
566
+ */
567
+ createToolbar: function() {
568
+
569
+ // Create and set the toolbar
570
+ this.toolbar.set(
571
+ new wp.media.view.Toolbar({
572
+ controller: this,
573
+ items: {
574
+ select: {
575
+ style: 'primary',
576
+ text: _easingsliderAdminL10n.media_upload.update,
577
+ priority: 80,
578
+ click: function() {
579
+
580
+ // Establish variables
581
+ var controller = this.controller,
582
+ state = controller.state();
583
+
584
+ // Close the frame
585
+ controller.close();
586
+
587
+ // Trigger update
588
+ state.trigger('update', controller.model.toJSON());
589
+
590
+ // Restore and reset the default state
591
+ controller.setState(controller.options.state);
592
+ controller.reset();
593
+
594
+ }
595
+ }
596
+ }
597
+ })
598
+ );
599
+
600
+ },
601
+
602
+ /**
603
+ * Creates our states
604
+ */
605
+ createStates: function() {
606
+
607
+ // Add our "Edit Slide" state
608
+ this.states.add([
609
+ new Admin.controller.EditSlide.get({
610
+ type: this.model.get('type')
611
+ })
612
+ ]);
613
+
614
+ // Call parent states
615
+ wp.media.view.MediaFrame.Select.prototype.createStates.apply(this, arguments);
616
+
617
+ },
618
+
619
+ /**
620
+ * Renders the frame
621
+ */
622
+ render: function() {
623
+
624
+ // Call parent
625
+ wp.media.view.MediaFrame.Select.prototype.render.apply(this, arguments);
626
+
627
+ // Toggle navigation
628
+ this.toggleNav();
629
+
630
+ return this;
631
+
632
+ },
633
+
634
+ /**
635
+ * Rerenders the frame
636
+ */
637
+ rerender: function() {
638
+
639
+ // Rerender the content region
640
+ this.content.render();
641
+
642
+ // Toggle navigation
643
+ this.toggleNav();
644
+
645
+ return this;
646
+
647
+ },
648
+
649
+ /**
650
+ * Toggles the navigation
651
+ */
652
+ toggleNav: function() {
653
+
654
+ // Reset navigation
655
+ this.$('.left').removeProp('disabled').removeClass('disabled');
656
+ this.$('.right').removeProp('disabled').removeClass('disabled');
657
+
658
+ // Toggle previous
659
+ if ( ! this.hasPrevious() ) {
660
+ this.$('.left').prop('disabled', 'disabled').addClass('disabled');
661
+ }
662
+
663
+ // Toggle next
664
+ if ( ! this.hasNext() ) {
665
+ this.$('.right').prop('disabled', 'disabled').addClass('disabled');
666
+ }
667
+
668
+ return this;
669
+
670
+ },
671
+
672
+ /**
673
+ * Click handler to switch to the previous slide
674
+ */
675
+ previousSlide: function() {
676
+
677
+ // Bail if we don't have a previous slide
678
+ if ( ! this.hasPrevious() ) {
679
+ this.$('.left').blur();
680
+ return;
681
+ }
682
+
683
+ // Set the new model
684
+ this.model = this.collection.at(this.collection.indexOf(this.model) - 1);
685
+
686
+ // Rerender the view
687
+ this.rerender();
688
+
689
+ // Focus navigation arrow
690
+ this.$('.left').focus();
691
+
692
+ },
693
+
694
+ /**
695
+ * Click handler to switch to the next slide
696
+ */
697
+ nextSlide: function() {
698
+
699
+ // Bail if we don't have a next slide
700
+ if ( ! this.hasNext() ) {
701
+ this.$('.right').blur();
702
+ return;
703
+ }
704
+
705
+ // Set the new model
706
+ this.model = this.collection.at(this.collection.indexOf(this.model) + 1);
707
+
708
+ // Rerender the view
709
+ this.rerender();
710
+
711
+ // Focus navigation arrow
712
+ this.$( '.right' ).focus();
713
+
714
+ },
715
+
716
+ /**
717
+ * Checks if we have a next slide
718
+ */
719
+ hasNext: function() {
720
+
721
+ return ( this.collection.indexOf(this.model) + 1 ) < this.collection.length;
722
+
723
+ },
724
+
725
+ /**
726
+ * Checks if we have a previous slide
727
+ */
728
+ hasPrevious: function() {
729
+
730
+ return ( this.collection.indexOf(this.model) - 1 ) > -1;
731
+
732
+ },
733
+
734
+ /**
735
+ * Updates the URL when the frame is closed
736
+ */
737
+ updateRouter: function() {
738
+
739
+ Admin.Router.navigate(_easingsliderAdminL10n.base_url);
740
+
741
+ }
742
+
743
+ });
744
+
745
+ /**
746
+ * Image "Edit Slide" Frame
747
+ */
748
+ Admin.frame.EditSlide.image = Admin.frame.EditSlide.base.extend({
749
+
750
+ /**
751
+ * Constructor
752
+ */
753
+ initialize: function() {
754
+
755
+ // Set the image
756
+ this.image = new wp.media.model.PostImage(this.model.attributes);
757
+
758
+ // Call parent constructor
759
+ Admin.frame.EditSlide.base.prototype.initialize.apply(this, arguments);
760
+
761
+ },
762
+
763
+ /**
764
+ * Bind event handlers
765
+ */
766
+ bindHandlers: function() {
767
+
768
+ // Bind events
769
+ this.on('content:create:browse', this.modifyBrowseFilters, this);
770
+ this.on('content:render:browse', this.removeBrowseSidebar, this);
771
+ this.on('content:render:edit-slide', this.showNav, this);
772
+ this.on('content:render:edit-image', this.renderEditImageContent, this);
773
+ this.on('toolbar:render:replace', this.hideNav, this);
774
+ this.on('toolbar:render:replace', this.renderReplaceImageToolbar, this);
775
+ this.state('replace-image').on('replace', this.replaceImage, this);
776
+
777
+ // Call parent
778
+ Admin.frame.EditSlide.base.prototype.bindHandlers.apply(this, arguments);
779
+
780
+ },
781
+
782
+ /**
783
+ * Create our states
784
+ */
785
+ createStates: function() {
786
+
787
+ // Call parent
788
+ Admin.frame.EditSlide.base.prototype.createStates.apply(this, arguments);
789
+
790
+ // Add "Edit" and "Replace" image states
791
+ this.states.add([
792
+ new wp.media.controller.ReplaceImage({
793
+ id: 'replace-image',
794
+ library: wp.media.query({ type: 'image' }),
795
+ image: this.image,
796
+ multiple: false,
797
+ title: _easingsliderAdminL10n.media_upload.replace_image,
798
+ toolbar: 'replace',
799
+ priority: 80,
800
+ displaySettings: true
801
+ }),
802
+ new wp.media.controller.EditImage( {
803
+ image: this.image,
804
+ selection: this.options.selection
805
+ } )
806
+ ]);
807
+
808
+ },
809
+
810
+ /**
811
+ * Overrides the Media Library browser filters, as the default filters aren't suitable.
812
+ */
813
+ modifyBrowseFilters: function(contentRegion) {
814
+
815
+ // Set the filters state
816
+ this.state().set('filterable', true);
817
+
818
+ },
819
+
820
+ /**
821
+ * Removes the sidebar from the Media Library browser
822
+ */
823
+ removeBrowseSidebar: function(view) {
824
+
825
+ // Remove the sidebar and hide it's element
826
+ view.sidebar.remove('details');
827
+ view.$el.addClass('hide-sidebar');
828
+
829
+ },
830
+
831
+ /**
832
+ * Show the navigation
833
+ */
834
+ showNav: function() {
835
+
836
+ this.$('.left, .right').show();
837
+ $('.media-modal-close').removeClass('no-border');
838
+
839
+ },
840
+
841
+ /**
842
+ * Hide the navigation
843
+ */
844
+ hideNav: function() {
845
+
846
+ this.$('.left, .right').hide();
847
+ $('.media-modal-close').addClass('no-border');
848
+
849
+ },
850
+
851
+ /**
852
+ * Renders the "Edit Image" view in the frame
853
+ */
854
+ renderEditImageContent: function() {
855
+
856
+ // Establish variables
857
+ var state = this.state(),
858
+ model = state.get('image'),
859
+ view;
860
+
861
+ // Bail if we have no model
862
+ if ( ! model ) {
863
+ return;
864
+ }
865
+
866
+ // Initiate the "Edit Image" view
867
+ view = new wp.media.view.EditImage({ model: model, controller: this }).render();
868
+
869
+ // Set the frame content
870
+ this.content.set(view);
871
+
872
+ // After bringing in the frame, load the actual editor via an ajax call
873
+ view.loadEditor();
874
+
875
+ },
876
+
877
+ /**
878
+ * Renders the "Replace Image" toolbar in the frame
879
+ */
880
+ renderReplaceImageToolbar: function() {
881
+
882
+ // Establish variables
883
+ var frame = this,
884
+ lastState = frame.lastState(),
885
+ previous = lastState && lastState.id;
886
+
887
+ // Set the toolbar
888
+ this.toolbar.set(
889
+ new wp.media.view.Toolbar({
890
+ controller: this,
891
+ items: {
892
+ back: {
893
+ text: _easingsliderAdminL10n.media_upload.back,
894
+ priority: 20,
895
+ click: function() {
896
+
897
+ // Close or go back to previous state
898
+ if ( previous ) {
899
+ frame.setState(previous);
900
+ } else {
901
+ frame.close();
902
+ }
903
+
904
+ }
905
+ },
906
+ replace: {
907
+ style: 'primary',
908
+ text: _easingsliderAdminL10n.media_upload.replace,
909
+ priority: 80,
910
+ click: function() {
911
+
912
+ // Establish variables
913
+ var controller = this.controller,
914
+ state = controller.state(),
915
+ selection = state.get('selection'),
916
+ attachment = selection.single();
917
+
918
+ // Close controller
919
+ controller.close();
920
+
921
+ // Change attachment
922
+ controller.image.changeAttachment(attachment, state.display(attachment));
923
+
924
+ // Not sure if we want to use wp.media.string.image which will create a shortcode or
925
+ // perhaps wp.html.string to at least to build the <img />
926
+ state.trigger( 'replace', controller.image.toJSON() );
927
+
928
+ // Restore and reset the default state
929
+ controller.setState(controller.options.state);
930
+ controller.reset();
931
+
932
+ }
933
+ }
934
+ }
935
+ })
936
+ );
937
+
938
+ },
939
+
940
+ /**
941
+ * Replaces the image
942
+ *
943
+ * This functionality is only available to attachment,
944
+ * so we can safely assume this is one.
945
+ */
946
+ replaceImage: function() {
947
+
948
+ // Replace the attachment
949
+ this.model.set({ attachment_id: this.image.attachment.id });
950
+ this.model.attachment.set(this.image.attachment.attributes);
951
+
952
+ }
953
+
954
+ });
955
+
956
+ /**
957
+ * "Editor" View
958
+ */
959
+ Admin.view.Editor = Backbone.View.extend({
960
+
961
+ /**
962
+ * Our view element
963
+ */
964
+ el: '.wrap',
965
+
966
+ /**
967
+ * Events
968
+ */
969
+ events: {
970
+ 'click #add-slides': '_addSlide',
971
+ 'click #select-all': '_selectAll',
972
+ 'click #delete-slides': '_clickBulkDelete',
973
+ 'click #save': '_clickSave',
974
+ 'click .toolbar .edit': '_clickEdit',
975
+ 'click .toolbar .remove': '_clickDelete',
976
+ 'click .show-advanced-options': '_clickAdvancedOptions',
977
+ 'click .thumbnail': '_clickThumb',
978
+ 'click .select-mode-toggle-button': '_toggleMode',
979
+ 'click .sidebar-name': '_toggleWidget'
980
+ },
981
+
982
+ /**
983
+ * Constructor
984
+ */
985
+ initialize: function() {
986
+
987
+ // Initiate our subviews
988
+ this.subviews = {
989
+ AddSlide: new Admin.frame.AddSlide(),
990
+ Slides: new Admin.view.Slides({
991
+ collection: this.collection
992
+ })
993
+ };
994
+
995
+ // Bind our events
996
+ this.collection.on('sync:done', this.render, this);
997
+ this.collection.on('sync:done', this._enableSave, this);
998
+ this.collection.on('sync:done', this._handleNoSlides, this);
999
+ this.collection.on('add', this._handleNoSlides, this);
1000
+ this.collection.on('remove', this._handleNoSlides, this);
1001
+ this.subviews.AddSlide.on('insert', this._handleInsert, this);
1002
+
1003
+ // Change number of columns on window resize
1004
+ $(window).on('resize', this._setColumns.bind(this));
1005
+
1006
+ // Disable select mode
1007
+ this._selectMode = false;
1008
+
1009
+ // Set number of columns
1010
+ this._setColumns();
1011
+
1012
+ // Show the spinner
1013
+ this._showSpinner();
1014
+
1015
+ },
1016
+
1017
+ /**
1018
+ * Shows the spinner
1019
+ */
1020
+ _showSpinner: function() {
1021
+
1022
+ this.$('#slides-browser').append('<div class="spinner"></div>');
1023
+
1024
+ },
1025
+
1026
+ /**
1027
+ * Hides the spinner
1028
+ */
1029
+ _hideSpinner: function() {
1030
+
1031
+ this.$('#slides-browser .spinner').remove();
1032
+
1033
+ },
1034
+
1035
+ /**
1036
+ * Enables the save button
1037
+ */
1038
+ _enableSave: function() {
1039
+
1040
+ this.$('#save').prop('disabled', false);
1041
+
1042
+ },
1043
+
1044
+ /**
1045
+ * Handles save button click
1046
+ */
1047
+ _clickSave: function() {
1048
+
1049
+ this.$('#publishing-action .spinner').css({ 'display': 'block' });
1050
+
1051
+ },
1052
+
1053
+ /**
1054
+ * Sets the appropriate number of columns
1055
+ */
1056
+ _setColumns: function() {
1057
+
1058
+ var content = this.$('.media-frame-content'),
1059
+ previous_columns = content.attr('data-columns'),
1060
+ width = content.width();
1061
+
1062
+ // Continue if we have width
1063
+ if ( width ) {
1064
+
1065
+ // Calculate the maximum number of columns we can fit
1066
+ var columns = Math.min(Math.round(width / 145), 12) || 1;
1067
+
1068
+ // Change the number of columns if it's not the same as previously
1069
+ if ( ! previous_columns || previous_columns !== columns ) {
1070
+ content.attr('data-columns', columns);
1071
+ }
1072
+
1073
+ }
1074
+
1075
+ },
1076
+
1077
+ /**
1078
+ * Handles our slides hidden input when no slides exists
1079
+ */
1080
+ _handleNoSlides: function() {
1081
+
1082
+ if ( 0 == this.collection.length ) {
1083
+ this.$('form').prepend('<input type="hidden" id="slides" name="slides" value="[]" />');
1084
+ }
1085
+ else {
1086
+ this.$('input[name="slides"]').remove();
1087
+ }
1088
+
1089
+ },
1090
+
1091
+ /**
1092
+ * Handles slide(s) insert from the "Add Slide" frame view
1093
+ */
1094
+ _handleInsert: function(selection) {
1095
+
1096
+ // Add to the collection
1097
+ this.collection.add(selection.models);
1098
+
1099
+ },
1100
+
1101
+ /**
1102
+ * Handles a thumbnail click event
1103
+ */
1104
+ _clickThumb: function(event) {
1105
+
1106
+ event.preventDefault();
1107
+
1108
+ // Handle click based on mode
1109
+ if ( ! this._selectMode ) {
1110
+ this._editSlide(event);
1111
+ }
1112
+ else {
1113
+ this._toggleSelect(event);
1114
+ }
1115
+
1116
+ },
1117
+
1118
+ /**
1119
+ * Handles an "edit" button click event
1120
+ */
1121
+ _clickEdit: function(event) {
1122
+
1123
+ event.preventDefault();
1124
+
1125
+ this._editSlide(event);
1126
+
1127
+ },
1128
+
1129
+ /**
1130
+ * Handles a "delete" button click event
1131
+ */
1132
+ _clickDelete: function(event) {
1133
+
1134
+ event.preventDefault();
1135
+
1136
+ if ( confirm( _easingsliderAdminL10n.warn ) ) {
1137
+
1138
+ // Get the model ID
1139
+ var id = $(event.currentTarget).parents('.attachment').attr('data-id');
1140
+
1141
+ // Delete the model from the collection
1142
+ this.collection.remove(id);
1143
+
1144
+ }
1145
+
1146
+ },
1147
+
1148
+ /**
1149
+ * Handles a bulk delete button click
1150
+ */
1151
+ _clickBulkDelete: function(event) {
1152
+
1153
+ event.preventDefault();
1154
+
1155
+ if ( confirm( _easingsliderAdminL10n.warn ) ) {
1156
+
1157
+ // Delete the slides
1158
+ this._deleteSlides(event);
1159
+
1160
+ // Toggle mode
1161
+ this._toggleMode(event);
1162
+
1163
+ }
1164
+
1165
+ },
1166
+
1167
+ /**
1168
+ * Handles "advanced options" link click
1169
+ */
1170
+ _clickAdvancedOptions: function(event) {
1171
+
1172
+ event.preventDefault();
1173
+
1174
+ // Get the advanced options
1175
+ var $options = $(event.currentTarget).parent().find('.advanced-options');
1176
+
1177
+ // Find the closest advanced options and show it
1178
+ $options.toggleClass('hide');
1179
+
1180
+ },
1181
+
1182
+ /**
1183
+ * Toggles between "Bulk Select" mode
1184
+ */
1185
+ _toggleMode: function(event) {
1186
+
1187
+ event.preventDefault();
1188
+
1189
+ // Toggle mode
1190
+ if ( ! this._selectMode ) {
1191
+ this._selectMode = true;
1192
+ }
1193
+ else {
1194
+ this._selectMode = false;
1195
+ }
1196
+
1197
+ // Toggle select mode class
1198
+ this.$('.attachment').removeClass('selected details');
1199
+ this.$('.media-frame').toggleClass('mode-select');
1200
+ this.$('.media-toolbar div *').toggleClass('hide');
1201
+
1202
+ },
1203
+
1204
+ /**
1205
+ * Toggles selection of a slide on click
1206
+ */
1207
+ _toggleSelect: function(event) {
1208
+
1209
+ event.preventDefault()
1210
+
1211
+ // Highlight the thumbnail
1212
+ $(event.currentTarget).parents('.attachment').toggleClass('selected details');
1213
+
1214
+ },
1215
+
1216
+ /**
1217
+ * Toggles a sidebar settings widget metabox
1218
+ */
1219
+ _toggleWidget: function(event) {
1220
+
1221
+ event.preventDefault();
1222
+
1223
+ var $widget = $(event.currentTarget).parent(),
1224
+ $content = $widget.find('.sidebar-content');
1225
+
1226
+ // Bail if this is a fixed widget
1227
+ if ( $widget.hasClass('fixed') ) {
1228
+ return;
1229
+ }
1230
+
1231
+ // Close any open sidebar metaboxes
1232
+ this.$('.widgets-holder-wrap').each(function() {
1233
+ var $metabox = $(this);
1234
+
1235
+ if ( ! $metabox.hasClass('fixed') ) {
1236
+ $metabox.find('.sidebar-content').slideUp(200, function() {
1237
+ $metabox.addClass('closed');
1238
+ });
1239
+ }
1240
+ });
1241
+
1242
+ // Bail if the clicked widget is already open
1243
+ if ( ! $widget.hasClass('closed') ) {
1244
+ return;
1245
+ }
1246
+
1247
+ // Open the sidebar metabox
1248
+ $content.slideDown(200, function() {
1249
+ $widget.removeClass('closed');
1250
+ });
1251
+
1252
+ },
1253
+
1254
+ /**
1255
+ * Selects all of the slides
1256
+ */
1257
+ _selectAll: function(event) {
1258
+
1259
+ event.preventDefault();
1260
+
1261
+ // Highlight all the thumbnails
1262
+ this.$('.attachment').addClass('selected details');
1263
+
1264
+ },
1265
+
1266
+ /**
1267
+ * Deletes the currently selected slides
1268
+ */
1269
+ _deleteSlides: function(event) {
1270
+
1271
+ event.preventDefault();
1272
+
1273
+ // Establish variables
1274
+ var collection = this.collection,
1275
+ models = [];
1276
+
1277
+ // Loop through each slide and remove selected
1278
+ this.$('.attachment').each(function(index) {
1279
+
1280
+ // Check if this slide has been selected & add it to be removed if so.
1281
+ if ( $(this).hasClass('selected') ) {
1282
+ models.push(collection.at(index));
1283
+ }
1284
+
1285
+ });
1286
+
1287
+ // Remove the models from the collection
1288
+ this.collection.remove(models);
1289
+
1290
+ },
1291
+
1292
+ /**
1293
+ * Opens the "Add Slide" frame view on click
1294
+ */
1295
+ _addSlide: function(event) {
1296
+
1297
+ event.preventDefault();
1298
+
1299
+ // Open the frame
1300
+ this.addSlide();
1301
+
1302
+ // Navigate router
1303
+ Admin.Router.navigate(_easingsliderAdminL10n.base_url + '&add=true');
1304
+
1305
+ },
1306
+
1307
+ /**
1308
+ * Opens the "Add Slide" frame
1309
+ */
1310
+ addSlide: function() {
1311
+
1312
+ // Open the "Add Slide" frame
1313
+ this.subviews.AddSlide.open();
1314
+
1315
+ return this;
1316
+
1317
+ },
1318
+
1319
+ /**
1320
+ * Opens the "Edit Slide" frame on click
1321
+ */
1322
+ _editSlide: function(event) {
1323
+
1324
+ event.preventDefault();
1325
+
1326
+ // Get the slide ID
1327
+ var id = $(event.currentTarget).parents('.attachment').attr('data-id');
1328
+
1329
+ // Open the frame
1330
+ this.editSlide(id);
1331
+
1332
+ // Navigate router
1333
+ Admin.Router.navigate(_easingsliderAdminL10n.base_url + '&slide=' + id);
1334
+
1335
+ },
1336
+
1337
+ /**
1338
+ * Opens the "Edit Slide" frame
1339
+ */
1340
+ editSlide: function(id) {
1341
+
1342
+ // Create the frame
1343
+ this.subviews.EditSlide = new Admin.frame.EditSlide.get({
1344
+ collection: this.collection,
1345
+ model: this.collection.get(id)
1346
+ });
1347
+
1348
+ // Open the frame
1349
+ this.subviews.EditSlide.open();
1350
+
1351
+ return this;
1352
+
1353
+ },
1354
+
1355
+ /**
1356
+ * Adds a frame to "Add Slide"
1357
+ */
1358
+ newAddSlideFrame: function(options) {
1359
+
1360
+ var frame = this.subviews.AddSlide;
1361
+
1362
+ // Add our states to the "Add Slide" frame
1363
+ frame.states.add([
1364
+ new Admin.controller.AddSlide.get(options)
1365
+ ]);
1366
+
1367
+ // Render content
1368
+ frame.on('content:render:'+ options.content, function() {
1369
+
1370
+ // Create the view
1371
+ var view = new Admin.view.AddSlide.get({
1372
+ type: options.content,
1373
+ model: this.state().props,
1374
+ controller: this
1375
+ });
1376
+
1377
+ // Set the view
1378
+ this.content.set(view);
1379
+
1380
+ }, frame);
1381
+
1382
+ // Render toolbar
1383
+ frame.on('toolbar:render:'+ options.toolbar, function() {
1384
+
1385
+ // Create the toolbar
1386
+ var toolbar = new Admin.toolbar.AddSlide.get({
1387
+ type: options.toolbar,
1388
+ controller: this
1389
+ });
1390
+
1391
+ // Set the toolbar
1392
+ this.toolbar.set(toolbar);
1393
+
1394
+ }, frame);
1395
+
1396
+ },
1397
+
1398
+ /**
1399
+ * Renders the view
1400
+ */
1401
+ render: function() {
1402
+
1403
+ // Hide the spinner
1404
+ this._hideSpinner();
1405
+
1406
+ // Render the subview
1407
+ var slides = this.subviews.Slides.render().el;
1408
+
1409
+ // Add the slides to the view
1410
+ this.$('#slides-browser').append(slides);
1411
+
1412
+ return this;
1413
+
1414
+ }
1415
+
1416
+ });
1417
+
1418
+ /**
1419
+ * "Slides" View
1420
+ */
1421
+ Admin.view.Slides = Backbone.View.extend({
1422
+
1423
+ /**
1424
+ * Tagname
1425
+ */
1426
+ tagName: 'ul',
1427
+
1428
+ /**
1429
+ * Attributes
1430
+ */
1431
+ attributes: {
1432
+ 'class': 'attachments ui-sortable',
1433
+ 'tabindex': '-1'
1434
+ },
1435
+
1436
+ /**
1437
+ * Constructor
1438
+ */
1439
+ initialize: function() {
1440
+
1441
+ // Subviews
1442
+ this.subviews = [];
1443
+
1444
+ // Bind our collection events
1445
+ this.collection.on('add', this.add, this);
1446
+ this.collection.on('remove', this.render, this);
1447
+ this.collection.on('reset', this.render, this);
1448
+
1449
+ // Enable sorting
1450
+ this.$el.sortable({
1451
+ items: '.attachment',
1452
+ containment: 'parent',
1453
+ tolerance: 'pointer',
1454
+ stop: this._sort.bind(this)
1455
+ });
1456
+
1457
+ },
1458
+
1459
+ /**
1460
+ * Sorts the view
1461
+ */
1462
+ _sort: function(event, ui) {
1463
+
1464
+ // Get the model
1465
+ var model = this.collection.get(ui.item.context.dataset.id);
1466
+
1467
+ // Reposition the model in the collection
1468
+ this.collection.reposition(model, ui.item.index());
1469
+
1470
+ },
1471
+
1472
+ /**
1473
+ * Adds a subview
1474
+ */
1475
+ add: function(model) {
1476
+
1477
+ // Render and add the slide to the view
1478
+ var view = new Admin.view.Slide({
1479
+ model: model
1480
+ });
1481
+
1482
+ // Add the subview
1483
+ this.subviews.push(view);
1484
+
1485
+ // Render and append subview to this view
1486
+ this.$el.append(view.render().$el);
1487
+
1488
+ return this;
1489
+
1490
+ },
1491
+
1492
+ /**
1493
+ * Renders the view
1494
+ */
1495
+ render: function() {
1496
+
1497
+ this.subviews = [];
1498
+
1499
+ // Empty the view
1500
+ this.$el.empty();
1501
+
1502
+ // Render each subview
1503
+ _.each(this.collection.models, function(model) {
1504
+ this.add(model);
1505
+ }, this);
1506
+
1507
+ return this;
1508
+
1509
+ }
1510
+
1511
+ });
1512
+
1513
+ /**
1514
+ * "Slide" View
1515
+ */
1516
+ Admin.view.Slide = Backbone.View.extend({
1517
+
1518
+ /**
1519
+ * Tagname
1520
+ */
1521
+ tagName: 'li',
1522
+
1523
+ /**
1524
+ * Attributes
1525
+ */
1526
+ attributes: function() {
1527
+ return {
1528
+ 'role': 'checkbox',
1529
+ 'class': 'attachment save-ready',
1530
+ 'tabindex': '0',
1531
+ 'data-id': this.model.id
1532
+ };
1533
+ },
1534
+
1535
+ /**
1536
+ * Template for this view
1537
+ */
1538
+ template: wp.media.template('easingslider-slide'),
1539
+
1540
+ /**
1541
+ * Constructor
1542
+ */
1543
+ initialize: function() {
1544
+
1545
+ // Bind events
1546
+ this.model.on('change', this._setData, this);
1547
+ this.model.on('change:id', this._updateID, this);
1548
+ this.model.on('change:url', this.render, this);
1549
+ this.model.on('change:poster', this.render, this);
1550
+ this.model.on('change:attachment_id', this.render, this);
1551
+
1552
+ // Bind additional attachment events if appropriate
1553
+ if ( this.model.attachment ) {
1554
+ this.model.attachment.on('change', this.render, this);
1555
+ }
1556
+
1557
+ },
1558
+
1559
+ /**
1560
+ * Sets our data
1561
+ */
1562
+ _setData: function() {
1563
+
1564
+ // Set data in hidden input
1565
+ this.$('input[name="slides[]"]').val(JSON.stringify(this.model.attributes));
1566
+
1567
+ },
1568
+
1569
+ /**
1570
+ * Update our ID attribute
1571
+ */
1572
+ _updateID: function(model, value) {
1573
+
1574
+ // Update attrbitue on DOM
1575
+ this.$el.attr('data-id', value);
1576
+
1577
+ // Update attribute on view object
1578
+ this.attributes['data-id'] = value;
1579
+
1580
+ },
1581
+
1582
+ /**
1583
+ * Renders the view
1584
+ */
1585
+ render: function() {
1586
+
1587
+ var data = { model: this.model.toJSON() };
1588
+
1589
+ // If our model has an attachment, add it to the data.
1590
+ if ( this.model.attachment ) {
1591
+ data.attachment = this.model.attachment.toJSON();
1592
+ }
1593
+
1594
+ // Generate the template
1595
+ this.$el.html(this.template(data));
1596
+
1597
+ return this;
1598
+
1599
+ }
1600
+
1601
+ });
1602
+
1603
+ /**
1604
+ * Returns the appropriate "Add Slide" view
1605
+ */
1606
+ Admin.view.AddSlide = {
1607
+
1608
+ /**
1609
+ * Get the appropriate view
1610
+ */
1611
+ get: function(options) {
1612
+
1613
+ if ( 'undefined' !== typeof Admin.view.AddSlide[options.type] ) {
1614
+ return new Admin.view.AddSlide[options.type](options);
1615
+ }
1616
+
1617
+ return new Admin.view.AddSlide.base(options);
1618
+
1619
+ }
1620
+
1621
+ };
1622
+
1623
+ /**
1624
+ * Base "Add Slide" View
1625
+ */
1626
+ Admin.view.AddSlide.base = wp.media.View.extend();
1627
+
1628
+ /**
1629
+ * Image "Add Slide" View
1630
+ */
1631
+ Admin.view.AddSlide.image = wp.media.view.AttachmentsBrowser.extend();
1632
+
1633
+ /**
1634
+ * Returns the appropriate "Edit Slide" view
1635
+ */
1636
+ Admin.view.EditSlide = {
1637
+
1638
+ /**
1639
+ * Get the appropriate view
1640
+ */
1641
+ get: function(options) {
1642
+
1643
+ if ( 'undefined' !== typeof Admin.view.EditSlide[options.type] ) {
1644
+ return new Admin.view.EditSlide[options.type](options);
1645
+ }
1646
+
1647
+ return new Admin.view.EditSlide.base(options);
1648
+
1649
+ }
1650
+
1651
+ };
1652
+
1653
+ /**
1654
+ * Base "Edit Slide" View
1655
+ */
1656
+ Admin.view.EditSlide.base = wp.media.view.Settings.extend({
1657
+
1658
+ /**
1659
+ * Classname
1660
+ */
1661
+ className: 'edit-attachment-frame attachment-details mode-select',
1662
+
1663
+ /**
1664
+ * Template for this view
1665
+ */
1666
+ template: wp.media.template('easingslider-edit-slide'),
1667
+
1668
+ /**
1669
+ * Constructor
1670
+ */
1671
+ initialize: function() {
1672
+
1673
+ // Call parent constructor
1674
+ wp.media.view.Settings.prototype.initialize.apply(this, arguments);
1675
+
1676
+ // Bind events
1677
+ this.model.on('change:link', this.toggleLinkSettings, this);
1678
+ this.model.on('change:link', this.updateLinkTo, this);
1679
+
1680
+ },
1681
+
1682
+ /**
1683
+ * Prepares the view data
1684
+ */
1685
+ prepare: function() {
1686
+
1687
+ var attachment = false;
1688
+
1689
+ // Check model for attachment
1690
+ if ( this.model.attachment ) {
1691
+ attachment = this.model.attachment.toJSON();
1692
+ }
1693
+
1694
+ return _.defaults({
1695
+ model: this.model.toJSON(),
1696
+ attachment: attachment
1697
+ }, this.options );
1698
+
1699
+ },
1700
+
1701
+ /**
1702
+ * Adds support for "Link" options show/hide
1703
+ */
1704
+ toggleLinkSettings: function() {
1705
+
1706
+ if ( 'none' === this.model.get('link') ) {
1707
+ this.$('.link-options').addClass('hide');
1708
+ } else {
1709
+ this.$('.link-options').removeClass('hide');
1710
+ }
1711
+
1712
+ },
1713
+
1714
+ /**
1715
+ * Handles "Link To" option
1716
+ */
1717
+ updateLinkTo: function() {
1718
+
1719
+ var linkTo = this.model.get('link'),
1720
+ $input = this.$('.link-to-custom');
1721
+
1722
+ if ( this.model.attachment ) {
1723
+
1724
+ if ( 'none' === linkTo || 'embed' === linkTo || ( ! this.model.attachment && 'custom' !== linkTo ) ) {
1725
+ $input.addClass('hidden');
1726
+ return;
1727
+ }
1728
+
1729
+ if ( this.model.attachment ) {
1730
+ if ( 'post' === linkTo ) {
1731
+ $input.val(this.model.attachment.get('link'));
1732
+ } else if ( 'file' === linkTo ) {
1733
+ $input.val(this.model.attachment.get('url'));
1734
+ } else if ( ! this.model.get('linkUrl') ) {
1735
+ $input.val('http://');
1736
+ }
1737
+
1738
+ $input.prop('readonly', 'custom' !== linkTo);
1739
+ }
1740
+
1741
+ $input.removeClass('hidden');
1742
+
1743
+ // If the input is visible, focus and select its contents.
1744
+ if ( ! wp.media.isTouchDevice && $input.is(':visible') ) {
1745
+ $input.focus()[0].select();
1746
+ }
1747
+
1748
+ }
1749
+
1750
+ },
1751
+
1752
+ /**
1753
+ * Renders the view
1754
+ */
1755
+ render: function() {
1756
+
1757
+ // Call parent
1758
+ wp.media.view.Settings.prototype.render.apply(this, arguments);
1759
+
1760
+ // Set toggles
1761
+ this.toggleLinkSettings();
1762
+ this.updateLinkTo();
1763
+
1764
+ return this;
1765
+
1766
+ }
1767
+
1768
+ });
1769
+
1770
+ /**
1771
+ * Image "Edit Slide" View
1772
+ */
1773
+ Admin.view.EditSlide.image = Admin.view.EditSlide.base.extend({
1774
+
1775
+ /**
1776
+ * Events
1777
+ */
1778
+ events: _.defaults({
1779
+ 'click .edit-attachment': 'editAttachment',
1780
+ 'click .replace-attachment': 'replaceAttachment'
1781
+ }, Admin.view.EditSlide.base.prototype.events),
1782
+
1783
+ /**
1784
+ * Constructor
1785
+ */
1786
+ initialize: function() {
1787
+
1788
+ // Call parent constructor
1789
+ Admin.view.EditSlide.base.prototype.initialize.apply(this, arguments);
1790
+
1791
+ // Bind events
1792
+ this.model.on('change:url', this.updateImage, this);
1793
+
1794
+ },
1795
+
1796
+ /**
1797
+ * Changes to "Edit" state
1798
+ */
1799
+ editAttachment: function(event) {
1800
+
1801
+ // Get current state
1802
+ var editState = this.controller.states.get('edit-image');
1803
+
1804
+ // Continue if editing is allowed and we've an edit state
1805
+ if ( window.imageEdit && editState ) {
1806
+ event.preventDefault();
1807
+ editState.set('image', this.model.attachment);
1808
+ this.controller.setState('edit-image');
1809
+ }
1810
+
1811
+ },
1812
+
1813
+ /**
1814
+ * Changes to "Replace" state
1815
+ */
1816
+ replaceAttachment: function(event) {
1817
+
1818
+ event.preventDefault();
1819
+
1820
+ this.controller.setState('replace-image');
1821
+
1822
+ },
1823
+
1824
+ /**
1825
+ * Updates the image preview (URL images only)
1826
+ */
1827
+ updateImage: function() {
1828
+
1829
+ this.$('.details-image').attr('src', this.model.get('url'));
1830
+
1831
+ }
1832
+
1833
+ });
1834
+
1835
+ /**
1836
+ * Returns the appropriate "Add Slide" toolbar
1837
+ */
1838
+ Admin.toolbar.AddSlide = {
1839
+
1840
+ /**
1841
+ * Get the appropriate toolbar
1842
+ */
1843
+ get: function(options) {
1844
+
1845
+ if ( 'undefined' !== typeof Admin.toolbar.AddSlide[options.type] ) {
1846
+ return new Admin.toolbar.AddSlide[options.type](options);
1847
+ }
1848
+
1849
+ return new Admin.toolbar.AddSlide.base(options);
1850
+
1851
+ }
1852
+
1853
+ };
1854
+
1855
+ /**
1856
+ * Base "Add Slide" Toolbar
1857
+ */
1858
+ Admin.toolbar.AddSlide.base = wp.media.view.Toolbar.extend();
1859
+
1860
+ /**
1861
+ * Router
1862
+ */
1863
+ Admin.router = Backbone.Router.extend({
1864
+
1865
+ /**
1866
+ * Routes
1867
+ */
1868
+ routes: {
1869
+ 'admin.php?page=:page&edit=:id&slide=:slide': 'editSlide',
1870
+ 'admin.php?page=:page&edit=:id&add=true': 'addSlide',
1871
+ 'admin.php?page=:page&edit=:id': 'editor',
1872
+ 'admin.php?page=easingslider-add-new': 'editor'
1873
+ },
1874
+
1875
+ /**
1876
+ * Constructor
1877
+ */
1878
+ initialize: function() {
1879
+
1880
+ // Get the slides
1881
+ var slides = ( typeof window.slides === 'undefined' ) ? '[]' : window.slides;
1882
+
1883
+ // Initate our view
1884
+ this.view = new Admin.view.Editor({
1885
+ collection: new Admin.collection.Slides(JSON.parse(slides))
1886
+ });
1887
+
1888
+ },
1889
+
1890
+ /**
1891
+ * Shows the "Edit Slide" frame
1892
+ */
1893
+ editSlide: function(page, id, slide) {
1894
+
1895
+ // Load the admin editor
1896
+ this.editor();
1897
+
1898
+ // Once the colleciton has been synced, open the edit slide frame
1899
+ this.view.collection.on('sync:done', function() {
1900
+ this.view.editSlide(slide);
1901
+ }, this);
1902
+
1903
+ return this;
1904
+
1905
+ },
1906
+
1907
+ /**
1908
+ * Shows the "Add Slide" frame
1909
+ */
1910
+ addSlide: function(page, id) {
1911
+
1912
+ // Load the admin editor
1913
+ this.editor();
1914
+
1915
+ // Once the colleciton has been synced, open the add slide frame
1916
+ this.view.collection.on('sync:done', function() {
1917
+ this.view.addSlide();
1918
+ }, this);
1919
+
1920
+ return this;
1921
+
1922
+ },
1923
+
1924
+ /**
1925
+ * Shows the admin editor
1926
+ */
1927
+ editor: function(page) {
1928
+
1929
+ // Sync the collection & get the ball rolling!
1930
+ this.view.collection.sync();
1931
+
1932
+ return this;
1933
+
1934
+ }
1935
+
1936
+ });
1937
+
1938
+ /**
1939
+ * Let's go!
1940
+ */
1941
+ $(document).ready(function() {
1942
+
1943
+ // Initiate the router
1944
+ Admin.Router = new Admin.router();
1945
+
1946
+ // Start the history
1947
+ Backbone.history.start({
1948
+ root: window._easingsliderAdminL10n.admin_url,
1949
+ pushState: true,
1950
+ });
1951
+
1952
+ // Handly delete class
1953
+ $('.delete').each(function() {
1954
+ $(this).on('click', function() {
1955
+ if ( ! confirm( _easingsliderAdminL10n.warn ) ) {
1956
+ return false;
1957
+ }
1958
+ });
1959
+ });
1960
+
1961
+ // Change our slider type
1962
+ $('select[name="type"]').on('change', function() {
1963
+
1964
+ // Hide options
1965
+ $('*[data-type]').addClass('hidden');
1966
+ $('*[data-type="'+ this.value +'"]').removeClass('hidden');
1967
+
1968
+ // Hide primary toolbar when not using slides from "Media"
1969
+ if ( 'media' != this.value ) {
1970
+ $('.media-toolbar-primary').addClass('hidden');
1971
+ } else {
1972
+ $('.media-toolbar-primary').removeClass('hidden');
1973
+ }
1974
+
1975
+ });
1976
+
1977
+ /**
1978
+ * Handle addon activation
1979
+ */
1980
+ $(document).on('click', '.js-activate-addon', function(event) {
1981
+ event.preventDefault();
1982
+
1983
+ // Establish variables
1984
+ var $button = $(this);
1985
+ var $el = $button.parents('.addon-status');
1986
+ var $message = $el.find('.status-message');
1987
+
1988
+ // Remove errors
1989
+ $('.action-error').remove();
1990
+
1991
+ // Tell the user what's happening
1992
+ $button.text(_easingsliderAdminL10n.buttons.activating);
1993
+
1994
+ // Process the Ajax to perform the activation.
1995
+ var options = {
1996
+ url: ajaxurl,
1997
+ type: 'post',
1998
+ async: true,
1999
+ cache: false,
2000
+ dataType: 'json',
2001
+ data: {
2002
+ action: 'easingslider_activate_addon',
2003
+ nonce: _easingsliderAdminL10n.nonces.activate,
2004
+ plugin: $button.attr('data-plugin')
2005
+ },
2006
+ success: function(response) {
2007
+
2008
+ // If there is a WP Error instance, output it here and quit
2009
+ if ( response && true !== response ) {
2010
+ $button.after('<div class="action-error error"><strong>'+ response.error +'</strong></div>');
2011
+ return false;
2012
+ }
2013
+
2014
+ // The Ajax request was successful, update the button.
2015
+ $button
2016
+ .text(_easingsliderAdminL10n.buttons.deactivate)
2017
+ .removeClass('js-activate-addon')
2018
+ .addClass('js-deactivate-addon');
2019
+
2020
+ // Update message
2021
+ $message.text(_easingsliderAdminL10n.messages.active);
2022
+
2023
+ // Change status
2024
+ $el.removeClass('is-inactive').addClass('is-active');
2025
+
2026
+ },
2027
+ error: function(xhr, textStatus, event) {
2028
+ return false;
2029
+ }
2030
+ };
2031
+
2032
+ // Perform ajax request
2033
+ $.ajax(options);
2034
+ });
2035
+
2036
+ /**
2037
+ * Handle addon deactivation
2038
+ */
2039
+ $(document).on('click', '.js-deactivate-addon', function(event) {
2040
+ event.preventDefault();
2041
+
2042
+ // Establish variables
2043
+ var $button = $(this);
2044
+ var $el = $button.parents('.addon-status');
2045
+ var $message = $el.find('.status-message');
2046
+
2047
+ // Remove errors
2048
+ $('.action-error').remove();
2049
+
2050
+ // Tell the user what's happening
2051
+ $button.text(_easingsliderAdminL10n.buttons.deactivating);
2052
+
2053
+ // Process the Ajax to perform the activation.
2054
+ var options = {
2055
+ url: ajaxurl,
2056
+ type: 'post',
2057
+ async: true,
2058
+ cache: false,
2059
+ dataType: 'json',
2060
+ data: {
2061
+ action: 'easingslider_deactivate_addon',
2062
+ nonce: _easingsliderAdminL10n.nonces.deactivate,
2063
+ plugin: $button.attr('data-plugin')
2064
+ },
2065
+ success: function(response) {
2066
+
2067
+ // If there is a WP Error instance, output it here and quit
2068
+ if ( response && true !== response ) {
2069
+ $button.after('<div class="action-error error"><strong>'+ response.error +'</strong></div>');
2070
+ return false;
2071
+ }
2072
+
2073
+ // The Ajax request was successful, update the button.
2074
+ $button
2075
+ .text(_easingsliderAdminL10n.buttons.activate)
2076
+ .removeClass('js-deactivate-addon')
2077
+ .addClass('js-activate-addon');
2078
+
2079
+ // Update message
2080
+ $message.text(_easingsliderAdminL10n.messages.inactive);
2081
+
2082
+ // Change status
2083
+ $el.removeClass('is-active').addClass('is-inactive');
2084
+
2085
+ },
2086
+ error: function(xhr, textStatus, event) {
2087
+ return false;
2088
+ }
2089
+ };
2090
+
2091
+ // Perform ajax request
2092
+ $.ajax(options);
2093
+ });
2094
+
2095
+ /**
2096
+ * Handle addon installation
2097
+ */
2098
+ $(document).on('click', '.js-install-addon', function(event) {
2099
+ event.preventDefault();
2100
+
2101
+ // Establish variables
2102
+ var $button = $(this);
2103
+ var $el = $button.parents('.addon-status');
2104
+ var $message = $el.find('.status-message');
2105
+
2106
+ // Remove errors
2107
+ $('.action-error').remove();
2108
+
2109
+ // Tell the user what's happening
2110
+ $button.text(_easingsliderAdminL10n.buttons.installing);
2111
+
2112
+ // Process the Ajax to perform the activation.
2113
+ var options = {
2114
+ url: ajaxurl,
2115
+ type: 'post',
2116
+ async: true,
2117
+ cache: false,
2118
+ dataType: 'json',
2119
+ data: {
2120
+ action: 'easingslider_install_addon',
2121
+ nonce: _easingsliderAdminL10n.nonces.install,
2122
+ plugin: $button.attr('data-plugin')
2123
+ },
2124
+ success: function(response) {
2125
+
2126
+ // If there is a WP Error instance, output it here and quit
2127
+ if ( response.error ) {
2128
+ $button.after('<div class="action-error error"><strong>'+ response.error +'</strong></div>');
2129
+ return false;
2130
+ }
2131
+
2132
+ // The Ajax request was successful, update the button.
2133
+ $button
2134
+ .attr('data-plugin', response.plugin)
2135
+ .text(_easingsliderAdminL10n.buttons.activate)
2136
+ .removeClass('js-install-addon')
2137
+ .addClass('js-activate-addon');
2138
+
2139
+ // Update message
2140
+ $message.text(_easingsliderAdminL10n.messages.inactive);
2141
+
2142
+ // Change status
2143
+ $el.removeClass('not-installed').addClass('is-inactive');
2144
+
2145
+ },
2146
+ error: function(xhr, textStatus, event) {
2147
+ return false;
2148
+ }
2149
+ };
2150
+
2151
+ // Perform ajax request
2152
+ $.ajax(options);
2153
+ });
2154
+
2155
+ });
2156
+
2157
+ })(jQuery);
resources/assets/js/public.js ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($) {
2
+
3
+ /**
4
+ * jQuery Easing Slider
5
+ *
6
+ * This is essentially a container for our interactions with Owl Carousel, aliased as `$.easingSlider` to avoid conflicts.
7
+ * We're relying on it as our third-party slider script, plus some additional functionality to enhance.
8
+ */
9
+ $.EasingSlider = function(el) {
10
+
11
+ // Core variables
12
+ var base = this;
13
+
14
+ // Establish our elements
15
+ base.el = el;
16
+ base.$el = $(base.el);
17
+ base.$wrapper = base.$el.find('.easingslider-wrapper');
18
+ base.$slides = base.$el.find('.easingslider-slide');
19
+ base.$images = base.$el.find('.easingslider-image');
20
+
21
+ // Get options
22
+ base.options = window['EasingSlider'+ base.$el.attr('data-id')];
23
+
24
+ // Determine click event
25
+ base._clickEvent = ( 'ontouchstart' in document.documentElement ) ? 'touchstart' : 'click';
26
+
27
+ // Store our data for external access
28
+ base.$el.data('easingslider', base);
29
+
30
+ /**
31
+ * Initiates the slider
32
+ */
33
+ base.initSlider = function() {
34
+
35
+ // Initiate Owl Carousel (aliased as $.easingSlider to avoid conflicts)
36
+ base.$el.easingSlider($.extend(base.options, {
37
+ afterInit: function() {
38
+ base._maybeResize();
39
+ },
40
+ afterUpdate: function() {
41
+ base._maybeResize();
42
+ },
43
+ afterAction: function() {
44
+ base.$el.trigger('changeSlide', this.currentItem);
45
+ }
46
+ }));
47
+
48
+ };
49
+
50
+ /**
51
+ * Resizes the slider if aspect ratio is enabled
52
+ */
53
+ base._maybeResize = function() {
54
+
55
+ // Resize if maintaining aspect ratio
56
+ if ( base.$el.hasClass('easingslider-aspect-ratio') ) {
57
+ base.doResize();
58
+ }
59
+
60
+ return base;
61
+
62
+ };
63
+
64
+ /**
65
+ * Executes a resize
66
+ */
67
+ base.doResize = function() {
68
+
69
+ // Get the current width & wrapper width
70
+ var currentWidth = base.$el.outerWidth();
71
+
72
+ // Get the outer wrapper
73
+ var outerWrapper = base.$el.find('.easingslider-wrapper-outer');
74
+
75
+ // If it has changed, resize the height to match.
76
+ if ( currentWidth <= base.options.width ) {
77
+
78
+ // Using the default slider width, let's calculate the percentage change and thus calculate the new height.
79
+ var newHeight = Math.floor((currentWidth / base.options.width) * base.options.height);
80
+
81
+ // Set the wrapper height
82
+ base.$el.css({ 'height': newHeight +'px' });
83
+ base.$wrapper.css({ 'height': newHeight +'px' });
84
+ base.$images.css({ 'max-height': newHeight +'px' });
85
+
86
+ } else {
87
+
88
+ // Set image height(s) only
89
+ base.$el.css({ 'height': base.options.height +'px' });
90
+ base.$wrapper.css({ 'height': base.options.height +'px' });
91
+ base.$images.css({ 'max-height': base.options.height +'px' });
92
+
93
+ }
94
+
95
+ // Prevent subpixel rendering by rounding width
96
+ outerWrapper.css({ 'width': Math.floor(outerWrapper.outerWidth()) +'px' });
97
+
98
+ return base;
99
+
100
+ };
101
+
102
+ // Initialize plugin
103
+ base.initSlider();
104
+
105
+ };
106
+
107
+ /**
108
+ * Initiate slider(s)
109
+ */
110
+ $.fn.EasingSlider = function() {
111
+ return this.each(function() {
112
+ new $.EasingSlider(this);
113
+ });
114
+ };
115
+
116
+ /**
117
+ * Let's go!
118
+ */
119
+ $(document).ready(function() {
120
+ $('.easingslider').EasingSlider();
121
+ });
122
+
123
+ })(jQuery);
resources/backbone/tmpl-edit-slide-frame.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="tmpl-easingslider-edit-slide-frame">
2
+ <div class="edit-media-header">
3
+ <button class="left dashicons"><span class="screen-reader-text"><?php _e('Edit previous media item', 'easingslider'); ?></span></button>
4
+ <button class="right dashicons"><span class="screen-reader-text"><?php _e('Edit next media item', 'easingslider'); ?></span></button>
5
+ </div>
6
+ <div class="media-frame-title"></div>
7
+ <div class="media-frame-content"></div>
8
+ <div class="media-frame-toolbar"></div>
9
+ </script>
backbone/edit-slide.php → resources/backbone/tmpl-edit-slide.php RENAMED
@@ -1,14 +1,14 @@
1
  <script type="text/html" id="tmpl-easingslider-edit-slide">
2
  <div class="attachment-media-view {{ data.model.orientation }}">
3
  <div class="thumbnail thumbnail-{{ data.type }}">
4
- <# if ( 'image' == data.model.type ) { #>
5
- <# if ( data.attachment ) { #>
6
  <img class="details-image" src="{{ data.attachment.url }}" draggable="false" />
7
 
8
- <# if ( window.imageEdit ) { #>
9
  <div class="actions">
10
- <input type="button" class="edit-attachment button" value="<?php _e( 'Edit Original' ); ?>" />
11
- <input type="button" class="replace-attachment button" value="<?php _e( 'Replace' ); ?>" />
12
  </div>
13
  <# } #>
14
  <# } else { #>
@@ -19,47 +19,47 @@
19
  </div>
20
  <# } #>
21
  <# } #>
22
-
23
  <?php
24
  /**
25
  * This is for our extensions and their custom slide preview
26
  */
27
- do_action( 'easingslider_print_edit_slide_preview' );
28
  ?>
29
  </div>
30
  </div>
31
 
32
  <div class="attachment-info">
33
- <# if ( 'image' == data.model.type ) { #>
34
  <div class="settings">
35
- <h3><?php _e( 'Link Settings', 'easingslider' ); ?></h3>
36
 
37
  <label class="setting link-to">
38
- <span class="name"><?php _e( 'Link To', 'easingslider' ); ?></span>
39
  <select data-setting="link">
40
  <option value="none">
41
- <?php _e( 'None', 'easingslider' ); ?>
42
  </option>
43
  <option value="custom">
44
- <?php _e( 'Custom URL', 'easingslider' ); ?>
45
  </option>
46
- <# if ( data.attachment ) { #>
47
  <option value="file">
48
- <?php _e( 'Media File', 'easingslider' ); ?>
49
  </option>
50
  <option value="post">
51
- <?php _e( 'Attachment Page', 'easingslider' ); ?>
52
  </option>
53
  <# } else { #>
54
  <option value="file">
55
- <?php _e( 'Image URL', 'easingslider' ); ?>
56
  </option>
57
  <# } #>
58
  </select>
59
  <div class="link-options">
60
  <input type="text" class="link-to-custom" data-setting="linkUrl" />
61
  <label>
62
- <input type="checkbox" data-setting="linkTargetBlank" value="_blank" <# if ( data.model.linkTargetBlank ) { #>checked="checked"<# } #>><?php _e( 'Open link in a new window/tab', 'easingslider' ); ?>
63
  </label>
64
  </div>
65
  </label>
@@ -68,20 +68,20 @@
68
  /**
69
  * This is for our extensions to add their own link settings
70
  */
71
- do_action( 'easingslider_print_link_to_settings' );
72
  ?>
73
  </div>
74
 
75
  <div class="settings">
76
- <h3><?php _e( 'Image Settings', 'easingslider' ); ?></h3>
77
 
78
  <label class="setting title">
79
- <span class="name"><?php _e( 'Title Attribute', 'easingslider' ); ?></span>
80
  <input type="text" data-setting="title" />
81
  </label>
82
 
83
  <label class="setting alt-text">
84
- <span class="name"><?php _e( 'Alternative Text', 'easingslider' ); ?></span>
85
  <input type="text" data-setting="alt" />
86
  </label>
87
  </div>
@@ -91,7 +91,7 @@
91
  /**
92
  * This is for our extensions and their custom slide settings
93
  */
94
- do_action( 'easingslider_print_edit_slide_settings' );
95
  ?>
96
  </div>
97
- </script>
1
  <script type="text/html" id="tmpl-easingslider-edit-slide">
2
  <div class="attachment-media-view {{ data.model.orientation }}">
3
  <div class="thumbnail thumbnail-{{ data.type }}">
4
+ <# if ('image' == data.model.type) { #>
5
+ <# if (data.attachment) { #>
6
  <img class="details-image" src="{{ data.attachment.url }}" draggable="false" />
7
 
8
+ <# if (window.imageEdit) { #>
9
  <div class="actions">
10
+ <input type="button" class="edit-attachment button" value="<?php _e('Edit Original', 'easingslider'); ?>" />
11
+ <input type="button" class="replace-attachment button" value="<?php _e('Replace', 'easingslider'); ?>" />
12
  </div>
13
  <# } #>
14
  <# } else { #>
19
  </div>
20
  <# } #>
21
  <# } #>
22
+
23
  <?php
24
  /**
25
  * This is for our extensions and their custom slide preview
26
  */
27
+ do_action('easingslider_print_edit_slide_preview');
28
  ?>
29
  </div>
30
  </div>
31
 
32
  <div class="attachment-info">
33
+ <# if ('image' == data.model.type) { #>
34
  <div class="settings">
35
+ <h3><?php _e('Link Settings', 'easingslider'); ?></h3>
36
 
37
  <label class="setting link-to">
38
+ <span class="name"><?php _e('Link To', 'easingslider'); ?></span>
39
  <select data-setting="link">
40
  <option value="none">
41
+ <?php _e('None', 'easingslider'); ?>
42
  </option>
43
  <option value="custom">
44
+ <?php _e('Custom URL', 'easingslider'); ?>
45
  </option>
46
+ <# if (data.attachment) { #>
47
  <option value="file">
48
+ <?php _e('Media File', 'easingslider'); ?>
49
  </option>
50
  <option value="post">
51
+ <?php _e('Attachment Page', 'easingslider'); ?>
52
  </option>
53
  <# } else { #>
54
  <option value="file">
55
+ <?php _e('Image URL', 'easingslider'); ?>
56
  </option>
57
  <# } #>
58
  </select>
59
  <div class="link-options">
60
  <input type="text" class="link-to-custom" data-setting="linkUrl" />
61
  <label>
62
+ <input type="checkbox" data-setting="linkTargetBlank" value="_blank" <# if (data.model.linkTargetBlank) { #>checked="checked"<# } #>><?php _e('Open link in a new window/tab', 'easingslider'); ?>
63
  </label>
64
  </div>
65
  </label>
68
  /**
69
  * This is for our extensions to add their own link settings
70
  */
71
+ do_action('easingslider_print_link_to_settings');
72
  ?>
73
  </div>
74
 
75
  <div class="settings">
76
+ <h3><?php _e('Image Settings', 'easingslider'); ?></h3>
77
 
78
  <label class="setting title">
79
+ <span class="name"><?php _e('Title Attribute', 'easingslider'); ?></span>
80
  <input type="text" data-setting="title" />
81
  </label>
82
 
83
  <label class="setting alt-text">
84
+ <span class="name"><?php _e('Alternative Text', 'easingslider'); ?></span>
85
  <input type="text" data-setting="alt" />
86
  </label>
87
  </div>
91
  /**
92
  * This is for our extensions and their custom slide settings
93
  */
94
+ do_action('easingslider_print_edit_slide_settings');
95
  ?>
96
  </div>
97
+ </script>
resources/backbone/tmpl-slide.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="tmpl-easingslider-slide">
2
+ <div class="attachment-preview {{ data.model.type }}-slide js--select-attachment">
3
+ <div class="toolbar">
4
+ <i class="dashicons dashicons-edit edit"></i>
5
+ <i class="dashicons dashicons-no-alt remove"></i>
6
+ </div>
7
+
8
+ <div class="thumbnail">
9
+ <# if ('image' === data.model.type) { #>
10
+ <# if (data.attachment && data.attachment.sizes) { #>
11
+ <# var image = data.attachment.sizes.thumbnail || data.attachment.sizes.medium || data.attachment.sizes.large || data.attachment.sizes.full #>
12
+ <div class="centered">
13
+ <img src="{{ image.url }}" draggable="true" alt="" />
14
+ </div>
15
+ <# } else { #>
16
+ <div class="centered">
17
+ <img src="{{ data.model.url }}" class="external-image" draggable="true" alt="" />
18
+ </div>
19
+ <div class="filename">
20
+ <div>
21
+ <span class="dashicons dashicons-admin-links thumbnail-dashicon"></span>
22
+ <?php _e('Ext. Image', 'easingslider'); ?>
23
+ </div>
24
+ </div>
25
+ <# } #>
26
+ <# } #>
27
+
28
+ <?php
29
+ /**
30
+ * This is for our extensions and their custom thumbnails
31
+ */
32
+ do_action('easingslider_print_thumbnail');
33
+ ?>
34
+ </div>
35
+ </div>
36
+
37
+ <a class="check" href="#" title="<?php esc_attr_e('Deselect'); ?>" tabindex="-1"><div class="media-modal-icon"></div></a>
38
+
39
+ <?php
40
+ /**
41
+ * This hidden attribute is kept in-sync with our model data.
42
+ * Everytime a change is made to the model, it's data is dumped here so we can fetch it with PHP.
43
+ */
44
+ ?>
45
+ <input type="hidden" name="slides[]" value="{{ JSON.stringify(data.model) }}" />
46
+ </script>
resources/views/edit-settings.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap">
2
+ <h1 class="nav-tab-wrapper">
3
+ <?php
4
+ foreach ($tabs as $tabID => $tab_name) :
5
+
6
+ // Get tab URL
7
+ $tab_url = add_query_arg(array(
8
+ 'tab' => $tabID
9
+ ));
10
+
11
+ // Print the tab
12
+ ?>
13
+ <a href="<?php echo esc_url($tab_url); ?>" title="<?php echo esc_attr($tab_name); ?>'" class="nav-tab <?php if ($activeTab == $tabID) { ?>nav-tab-active<?php } ?>">
14
+ <?php echo esc_html($tab_name); ?>
15
+ </a>
16
+ <?php
17
+
18
+ endforeach;
19
+ ?>
20
+ </h1>
21
+
22
+ <?php settings_errors(); ?>
23
+
24
+ <div id="tab_container">
25
+ <form method="post" action="options.php">
26
+ <table class="form-table">
27
+ <?php
28
+ settings_fields($optionName);
29
+ do_settings_fields("{$optionName}_{$activeTab}", "easingslider_settings_{$activeTab}");
30
+ ?>
31
+ </table>
32
+
33
+ <?php submit_button(); ?>
34
+ </form>
35
+ </div>
36
+ </div>
resources/views/edit-slider.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap">
2
+ <form id="slider" name="slider" action="admin.php?page=<?php echo esc_attr($page); if (isset($slider->ID)) { echo "&amp;edit=". esc_attr($slider->ID) .""; } ?>" method="post">
3
+ <input type="hidden" name="post_type" value="<?php echo esc_attr($slider->post_type); ?>">
4
+ <input type="hidden" name="post_status" value="<?php echo esc_attr($slider->post_status); ?>">
5
+
6
+ <?php if (isset($slider->ID)) : ?>
7
+ <input type="hidden" name="easingslider_action" value="update_slider">
8
+ <input type="hidden" name="id" value="<?php echo esc_attr($slider->ID); ?>">
9
+ <?php wp_nonce_field('update'); ?>
10
+ <?php else : ?>
11
+ <input type="hidden" name="easingslider_action" value="create_slider">
12
+ <?php wp_nonce_field('create'); ?>
13
+ <?php endif; ?>
14
+
15
+ <h1>
16
+ <?php if (isset($slider->ID)) : ?>
17
+ <?php _e('Edit Slider', 'easingslider'); ?>
18
+ <a href="admin.php?page=easingslider-add-new" class="page-title-action add-new-h2"><?php _e('Add New', 'easingslider'); ?></a>
19
+ <?php else : ?>
20
+ <?php _e('Add New Slider', 'easingslider'); ?>
21
+ <?php endif; ?>
22
+ </h1>
23
+
24
+ <div class="toolbar-container">
25
+ <div class="media-toolbar wp-filter">
26
+ <div class="media-toolbar-secondary title-form">
27
+ <label for="post_title"><?php _e('Name:', 'easingslider'); ?></label>
28
+ <input type="text" name="post_title" id="post_title" autocomplete="off" placeholder="<?php _e('Enter a slider name', 'easingslider'); ?>" value="<?php echo esc_attr($slider->post_title); ?>">
29
+ <a href="#" id="select-all" class="button media-button button-large hide"><?php _e('Select All', 'easingslider'); ?></a>
30
+ </div>
31
+
32
+ <div class="media-toolbar-primary <?php if ('media' != $slider->type) echo 'hidden'; ?>">
33
+ <label for="randomize" class="randomize">
34
+ <input type="hidden" name="randomize" value="false">
35
+ <input type="checkbox" id="randomize" name="randomize" value="true" <?php checked($slider->randomize, true); ?>><?php _e('Randomize the slide order', 'easingslider'); ?>
36
+ </label>
37
+ <a href="#" id="add-slides" class="button media-button button-primary button-large"><?php _e('Add Slides', 'easingslider'); ?></a>
38
+ <a href="#" id="bulk-select" class="button media-button button-large select-mode-toggle-button"><?php _e('Bulk Select', 'easingslider'); ?></a>
39
+ <a href="#" id="cancel-select" class="button media-button button-large select-mode-toggle-button hide"><?php _e('Cancel Selection', 'easingslider'); ?></a>
40
+ <a href="#" id="delete-slides" class="button media-button button-primary button-large hide"><?php _e('Delete Selected', 'easingslider'); ?></a>
41
+ </div>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="main-container clearfix">
46
+ <?php foreach ($types as $type => $label) : ?>
47
+ <div data-type="<?php echo esc_attr($type); ?>" class="slides-container <?php if ($type != $slider->type) echo 'hidden'; ?>">
48
+ <?php do_action("easingslider_admin_{$type}_slides_panel", $slider); ?>
49
+ </div>
50
+ <?php endforeach; ?>
51
+
52
+ <div class="settings-container sidebar-container">
53
+ <?php
54
+ /**
55
+ * Keep our settings sidebar in a separate file for clarity. Woohoo!
56
+ */
57
+ require 'edit-slider_sidebar.php';
58
+ ?>
59
+ </div>
60
+ </div>
61
+
62
+ <?php
63
+ /**
64
+ * This ensures that the slide's JSON is encoded correctly.
65
+ * Using PHP JSON encode can cause magic quote issues.
66
+ */
67
+ ?>
68
+ <script type="text/javascript">var slides = '<?php echo addslashes(json_encode($slider->slides)); ?>';</script>
69
+ </form>
70
+ </div>
resources/views/edit-slider_sidebar.php ADDED
@@ -0,0 +1,444 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Allow for additional boxes
4
+ */
5
+ do_action('easingslider_before_edit_slider_sidebar', $slider);
6
+ ?>
7
+
8
+ <!-- Publish -->
9
+ <div class="widgets-holder-wrap fixed">
10
+ <div class="sidebar-name">
11
+ <h3><?php _e('Publish', 'easingslider'); ?></h3>
12
+ </div>
13
+ <div class="sidebar-content widgets-sortables clearfix">
14
+ <?php
15
+ /**
16
+ * Allow for additional options
17
+ */
18
+ do_action('easingslider_publish_metabox_top', $slider);
19
+ ?>
20
+
21
+ <div class="misc-pub-section curtime misc-pub-curtime">
22
+ <span id="timestamp">
23
+ <?php if ( ! empty($slider->ID)) : ?>
24
+ <?php printf(__('Published on: <b>%s</b>', 'easingslider'), date('M j, Y @ G:i', strtotime($slider->post_date))); ?>
25
+ <?php else : ?>
26
+ <?php printf(__('Not published yet.', 'easingslider')); ?>
27
+ <?php endif; ?>
28
+ </span>
29
+ </div>
30
+
31
+ <?php
32
+ /**
33
+ * Allow for additional options
34
+ */
35
+ do_action('easingslider_publish_metabox_bottom', $slider);
36
+ ?>
37
+ </div>
38
+ <div id="major-publishing-actions">
39
+ <?php if ( ! empty($slider->ID)) : ?>
40
+ <div id="delete-action">
41
+ <a class="submitdelete deletion" href="<?php echo esc_attr(wp_nonce_url("?page={$page}&easingslider_action=trash_slider&id={$slider->ID}", 'trash')); ?>"><?php _e('Move to Trash', 'easingslider'); ?></a>
42
+ </div>
43
+ <?php endif; ?>
44
+ <div id="publishing-action">
45
+ <span class="spinner"></span>
46
+ <?php if ( ! empty($slider->ID)) : ?>
47
+ <input type="submit" name="save" class="button button-primary button-large" id="save" accesskey="p" disabled="disabled" value="<?php _e('Update', 'easingslider'); ?>">
48
+ <?php else : ?>
49
+ <input type="submit" name="publish" class="button button-primary button-large" id="publish" accesskey="p" value="<?php _e('Publish', 'easingslider'); ?>">
50
+ <?php endif; ?>
51
+ </div>
52
+ <div class="clear"></div>
53
+ </div>
54
+ </div>
55
+
56
+ <!-- Slider Type -->
57
+ <?php
58
+ /**
59
+ * No slider type options are displayed if we only have one type available.
60
+ * This is likely to be the default type, `media`.
61
+ */
62
+ ?>
63
+ <?php if (count($types) > 1) : ?>
64
+ <div class="widgets-holder-wrap open">
65
+ <div class="sidebar-name">
66
+ <div class="sidebar-name-arrow"></div>
67
+ <h3><?php _e('Slider Type', 'easingslider'); ?></h3>
68
+ </div>
69
+ <div class="sidebar-content widgets-sortables clearfix">
70
+ <?php
71
+ /**
72
+ * Allow for additional options
73
+ */
74
+ do_action('easingslider_slider_type_metabox_top', $slider);
75
+ ?>
76
+
77
+ <div>
78
+ <div class="field">
79
+ <label for="type">
80
+ <span><?php _e('Choose a Slider Type:', 'easingslider'); ?></span>
81
+ <select name="type" id="effect">
82
+ <?php foreach ($types as $type => $label) : ?>
83
+ <option value="<?php echo esc_attr($type); ?>" <?php selected($slider->type, $type); ?>><?php echo esc_html($label); ?></option>
84
+ <?php endforeach; ?>
85
+ </select>
86
+ </label>
87
+ </div>
88
+ <p class="description"><?php _e('Select a slider type above. Changing the type dictates where the slider sources its slides from.', 'easingslider'); ?></p>
89
+ </div>
90
+
91
+ <?php
92
+ /**
93
+ * Allow for additional options
94
+ */
95
+ do_action('easingslider_slider_type_metabox_bottom', $slider);
96
+ ?>
97
+ </div>
98
+ </div>
99
+ <?php endif; ?>
100
+
101
+ <!-- Dimensions -->
102
+ <div class="widgets-holder-wrap closed">
103
+ <div class="sidebar-name">
104
+ <div class="sidebar-name-arrow"></div>
105
+ <h3><?php _e('Dimensions', 'easingslider'); ?></h3>
106
+ </div>
107
+ <div class="sidebar-content widgets-sortables clearfix" style="display: none;">
108
+ <?php
109
+ /**
110
+ * Allow for additional options
111
+ */
112
+ do_action('easingslider_dimensions_metabox_top', $slider);
113
+ ?>
114
+
115
+ <div class="dimension-settings">
116
+ <div class="field half">
117
+ <label for="width">
118
+ <span><?php _e('Width:', 'easingslider'); ?></span>
119
+ <input type="number" name="width" id="width" value="<?php echo esc_attr($slider->width); ?>">
120
+ </label>
121
+ </div>
122
+ <div class="field half">
123
+ <label for="height">
124
+ <span><?php _e('Height:', 'easingslider'); ?></span>
125
+ <input type="number" name="height" id="height" value="<?php echo esc_attr($slider->height); ?>">
126
+ </label>
127
+ </div>
128
+ <div class="field field-extra">
129
+ <label for="full_width">
130
+ <input type="hidden" name="full_width" value="false">
131
+ <input type="checkbox" name="full_width" id="full_width" value="true" <?php checked($slider->full_width, true); ?>><span style="display: inline;"><?php _e('Make 100% full width.', 'easingslider'); ?></span>
132
+ </label>
133
+ </div>
134
+ <p class="description"><?php _e('Set the "width" and "height" values (in pixels). Enable the full width option to make the slider container 100% width.', 'easingslider'); ?></p>
135
+ </div>
136
+
137
+ <div>
138
+ <a href="#" class="show-advanced-options"><?php printf('+ %s', __('Show Advanced Options', 'easingslider')); ?></a>
139
+ <div class="advanced-options hide">
140
+ <div>
141
+ <div class="field">
142
+ <label for="image_resizing">
143
+ <input type="hidden" name="image_resizing" value="false">
144
+ <input type="checkbox" name="image_resizing" id="image_resizing" value="true" <?php checked($slider->image_resizing, true); ?>><span style="display: inline;"><?php _e('Crop & Resize images.', 'easingslider'); ?></span>
145
+ </label>
146
+ </div>
147
+ <p class="description"><?php _e('Crops & resizes images to fit the width and height specified above. Only works with images from the WordPress Media Library.', 'easingslider'); ?></p>
148
+ </div>
149
+
150
+ <div>
151
+ <div class="field">
152
+ <label for="auto_height">
153
+ <input type="hidden" name="auto_height" value="false">
154
+ <input type="checkbox" name="auto_height" id="auto_height" value="true" <?php checked($slider->auto_height, true); ?>><span style="display: inline;"><?php _e('Enable Adaptive Height.', 'easingslider'); ?></span>
155
+ </label>
156
+ </div>
157
+ <p class="description"><?php _e('Allows the slider to adapt to the height of each individual slide.', 'easingslider'); ?></p>
158
+ </div>
159
+ </div>
160
+ </div>
161
+
162
+ <?php
163
+ /**
164
+ * Allow for additional options
165
+ */
166
+ do_action('easingslider_dimensions_metabox_bottom', $slider);
167
+ ?>
168
+ </div>
169
+ </div>
170
+
171
+ <!-- Transitions -->
172
+ <div class="widgets-holder-wrap closed">
173
+ <div class="sidebar-name">
174
+ <div class="sidebar-name-arrow"></div>
175
+ <h3><?php _e('Transitions', 'easingslider'); ?></h3>
176
+ </div>
177
+ <div class="sidebar-content widgets-sortables clearfix" style="display: none;">
178
+ <?php
179
+ /**
180
+ * Allow for additional options
181
+ */
182
+ do_action('easingslider_transitions_metabox_top', $slider);
183
+ ?>
184
+
185
+ <div>
186
+ <div class="field">
187
+ <label for="effect">
188
+ <span><?php _e('Effect:', 'easingslider'); ?></span>
189
+ <select name="transition_effect" id="effect">
190
+ <?php foreach ($transitions as $transition => $label) : ?>
191
+ <option value="<?php echo esc_attr($transition); ?>" <?php selected($slider->transition_effect, $transition); ?>><?php echo esc_html($label); ?></option>
192
+ <?php endforeach; ?>
193
+ </select>
194
+ </label>
195
+ </div>
196
+ <p class="description"><?php _e('Choose the transition effect you would like to use.', 'easingslider'); ?></p>
197
+ </div>
198
+
199
+ <div>
200
+ <div class="field">
201
+ <label for="duration">
202
+ <span><?php _e('Duration:', 'easingslider'); ?></span>
203
+ <input type="number" name="transition_duration" id="duration" value="<?php echo esc_attr($slider->transition_duration); ?>">
204
+ </label>
205
+ </div>
206
+ <p class="description"><?php _e('Sets the duration (in milliseconds) for the slideshow transition.', 'easingslider'); ?></p>
207
+ </div>
208
+
209
+ <?php
210
+ /**
211
+ * Allow for additional options
212
+ */
213
+ do_action('easingslider_transitions_metabox_bottom', $slider);
214
+ ?>
215
+ </div>
216
+ </div>
217
+
218
+ <!-- Preloading -->
219
+ <div class="widgets-holder-wrap closed">
220
+ <div class="sidebar-name">
221
+ <div class="sidebar-name-arrow"></div>
222
+ <h3><?php _e('Preloading', 'easingslider'); ?></h3>
223
+ </div>
224
+ <div class="sidebar-content widgets-sortables clearfix" style="display: none;">
225
+ <?php
226
+ /**
227
+ * Allow for additional options
228
+ */
229
+ do_action('easingslider_preloading_metabox_top', $slider);
230
+ ?>
231
+
232
+ <div>
233
+ <div class="field">
234
+ <label for="lazy_loading">
235
+ <input type="hidden" name="lazy_loading" value="false">
236
+ <input type="checkbox" name="lazy_loading" id="lazy_loading" value="true" <?php checked($slider->lazy_loading, true); ?>><span style="display: inline;"><?php _e('Enable Lazy Loading.', 'easingslider'); ?></span>
237
+ </label>
238
+ </div>
239
+ <p class="description"><?php _e('Tick this option to enable slide lazy loading. Preloading images in this way can help reduce loading times and speed up your website.', 'easingslider'); ?></p>
240
+ </div>
241
+
242
+ <?php
243
+ /**
244
+ * Allow for additional options
245
+ */
246
+ do_action('easingslider_preloading_metabox_bottom', $slider);
247
+ ?>
248
+ </div>
249
+ </div>
250
+
251
+ <!-- Next & Previous Arrows -->
252
+ <div class="widgets-holder-wrap closed">
253
+ <div class="sidebar-name">
254
+ <div class="sidebar-name-arrow"></div>
255
+ <h3><?php _e('Next & Previous Arrows', 'easingslider'); ?></h3>
256
+ </div>
257
+ <div class="sidebar-content widgets-sortables" style="display: none;">
258
+ <?php
259
+ /**
260
+ * Allow for additional options
261
+ */
262
+ do_action('easingslider_arrows_metabox_top', $slider);
263
+ ?>
264
+
265
+ <div>
266
+ <div class="radio clearfix">
267
+ <span><?php _e('Arrows:', 'easingslider'); ?></span>
268
+ <div class="buttons">
269
+ <label for="arrows-enable"><input type="radio" name="arrows" id="arrows-enable" value="true" <?php checked($slider->arrows, true); ?>>
270
+ <span><?php _e('Enable', 'easingslider'); ?></span>
271
+ </label>
272
+ <label for="arrows-disable"><input type="radio" name="arrows" id="arrows-disable" value="false" <?php checked($slider->arrows, false); ?>>
273
+ <span><?php _e('Disable', 'easingslider'); ?></span>
274
+ </label>
275
+ </div>
276
+ </div>
277
+ <p class="description"><?php _e('Toggles the next and previous slide arrows.', 'easingslider'); ?></p>
278
+ </div>
279
+
280
+ <div>
281
+ <div class="radio clearfix">
282
+ <span><?php _e('On Hover:', 'easingslider'); ?></span>
283
+ <div class="buttons">
284
+ <label for="arrows-hover-true"><input type="radio" name="arrows_hover" id="arrows-hover-true" value="true" <?php checked($slider->arrows_hover, true); ?>>
285
+ <span><?php _e('True', 'easingslider'); ?></span>
286
+ </label>
287
+ <label for="arrows-hover-false"><input type="radio" name="arrows_hover" id="arrows-hover-false" value="false" <?php checked($slider->arrows_hover, false); ?>>
288
+ <span><?php _e('False', 'easingslider'); ?></span>
289
+ </label>
290
+ </div>
291
+ </div>
292
+ <p class="description"><?php _e('Set to "True" to only show the arrows when the user hovers over the slideshow.', 'easingslider'); ?></p>
293
+ </div>
294
+
295
+ <div>
296
+ <div class="field">
297
+ <label for="arrows_position">
298
+ <span><?php _e('Position:', 'easingslider'); ?></span>
299
+ <select name="arrows_position" id="arrows_position">
300
+ <option value="inside" <?php selected($slider->arrows_position, 'inside'); ?>><?php _e('Inside', 'easingslider'); ?></option>
301
+ <option value="outside" <?php selected($slider->arrows_position, 'outside'); ?>><?php _e('Outside', 'easingslider'); ?></option>
302
+ </select>
303
+ </label>
304
+ </div>
305
+ <p class="description"><?php _e('Select a position for the arrows.', 'easingslider'); ?></p>
306
+ </div>
307
+
308
+ <?php
309
+ /**
310
+ * Allow for additional options
311
+ */
312
+ do_action('easingslider_arrows_metabox_bottom', $slider);
313
+ ?>
314
+ </div>
315
+ </div>
316
+
317
+ <!-- Pagination Icons -->
318
+ <div class="widgets-holder-wrap closed">
319
+ <div class="sidebar-name">
320
+ <div class="sidebar-name-arrow"></div>
321
+ <h3><?php _e('Pagination Icons', 'easingslider'); ?></h3>
322
+ </div>
323
+ <div class="sidebar-content widgets-sortables" style="display: none;">
324
+ <?php
325
+ /**
326
+ * Allow for additional options
327
+ */
328
+ do_action('easingslider_pagination_metabox_top', $slider);
329
+ ?>
330
+
331
+ <div>
332
+ <div class="radio clearfix">
333
+ <span><?php _e('Pagination:', 'easingslider'); ?></span>
334
+ <div class="buttons">
335
+ <label for="pagination-enable"><input type="radio" name="pagination" id="pagination-enable" value="true" <?php checked($slider->pagination, true); ?>>
336
+ <span><?php _e('Enable', 'easingslider'); ?></span>
337
+ </label>
338
+ <label for="pagination-disable"><input type="radio" name="pagination" id="pagination-disable" value="false" <?php checked($slider->pagination, false); ?>>
339
+ <span><?php _e('Disable', 'easingslider'); ?></span>
340
+ </label>
341
+ </div>
342
+ </div>
343
+ <p class="description"><?php _e('Enable/Disable the Pagination Icons. Each icon represents a slide in their respective order.', 'easingslider'); ?></p>
344
+ </div>
345
+
346
+ <div>
347
+ <div class="radio clearfix">
348
+ <span><?php _e('On Hover:', 'easingslider'); ?></span>
349
+ <div class="buttons">
350
+ <label for="pagination-hover-true"><input type="radio" name="pagination_hover" id="pagination-hover-true" value="true" <?php checked($slider->pagination_hover, true); ?>>
351
+ <span><?php _e('True', 'easingslider'); ?></span>
352
+ </label>
353
+ <label for="pagination-hover-false"><input type="radio" name="pagination_hover" id="pagination-hover-false" value="false" <?php checked($slider->pagination_hover, false); ?>>
354
+ <span><?php _e('False', 'easingslider'); ?></span>
355
+ </label>
356
+ </div>
357
+ </div>
358
+ <p class="description"><?php _e('Set to "True" to only show the pagination when the user hovers over the slideshow.', 'easingslider'); ?></p>
359
+ </div>
360
+
361
+ <div>
362
+ <div class="field">
363
+ <label for="pagination_position">
364
+ <span><?php _e('Position:', 'easingslider'); ?></span>
365
+ <select name="pagination_position" id="pagination_position" style="width: 45%; float: left;">
366
+ <option value="inside" <?php selected($slider->pagination_position, 'inside'); ?>><?php _e('Inside', 'easingslider'); ?></option>
367
+ <option value="outside" <?php selected($slider->pagination_position, 'outside'); ?>><?php _e('Outside', 'easingslider'); ?></option>
368
+ </select>
369
+ <select name="pagination_location" id="pagination_location" style="width: 45%; float: left; margin-left: 10px;">
370
+ <option value="top-left" <?php selected($slider->pagination_location, 'top-left'); ?>><?php _e('Top Left', 'easingslider'); ?></option>
371
+ <option value="top-right" <?php selected($slider->pagination_location, 'top-right'); ?>><?php _e('Top Right', 'easingslider'); ?></option>
372
+ <option value="top-center" <?php selected($slider->pagination_location, 'top-center'); ?>><?php _e('Top Center', 'easingslider'); ?></option>
373
+ <option value="bottom-left" <?php selected($slider->pagination_location, 'bottom-left'); ?>><?php _e('Bottom Left', 'easingslider'); ?></option>
374
+ <option value="bottom-right" <?php selected($slider->pagination_location, 'bottom-right'); ?>><?php _e('Bottom Right', 'easingslider'); ?></option>
375
+ <option value="bottom-center" <?php selected($slider->pagination_location, 'bottom-center'); ?>><?php _e('Bottom Center', 'easingslider'); ?></option>
376
+ </select>
377
+ </label>
378
+ </div>
379
+ <p class="description"><?php _e('Select a position for the pagination icons.', 'easingslider'); ?></p>
380
+ </div>
381
+
382
+ <?php
383
+ /**
384
+ * Allow for additional options
385
+ */
386
+ do_action('easingslider_pagination_metabox_bottom', $slider);
387
+ ?>
388
+ </div>
389
+ </div>
390
+
391
+ <!-- Playback -->
392
+ <div class="widgets-holder-wrap closed">
393
+ <div class="sidebar-name">
394
+ <div class="sidebar-name-arrow"></div>
395
+ <h3><?php _e('Automatic Playback', 'easingslider'); ?></h3>
396
+ </div>
397
+ <div class="sidebar-content widgets-sortables" style="display: none;">
398
+ <?php
399
+ /**
400
+ * Allow for additional options
401
+ */
402
+ do_action('easingslider_playback_metabox_top', $slider);
403
+ ?>
404
+
405
+ <div>
406
+ <div class="radio clearfix">
407
+ <span><?php _e('Playback:', 'easingslider'); ?></span>
408
+ <div class="buttons">
409
+ <label for="playback-enable"><input type="radio" name="playback_enabled" id="playback-enable" value="true" <?php checked($slider->playback_enabled, true); ?>>
410
+ <span><?php _e('Enable', 'easingslider'); ?></span>
411
+ </label>
412
+ <label for="playback-disable"><input type="radio" name="playback_enabled" id="playback-disable" value="false" <?php checked($slider->playback_enabled, false); ?>>
413
+ <span><?php _e('Disable', 'easingslider'); ?></span>
414
+ </label>
415
+ </div>
416
+ </div>
417
+ <p class="description"><?php _e('Enable/Disable slideshow automatic playback.', 'easingslider'); ?></p>
418
+ </div>
419
+
420
+ <div>
421
+ <div class="field">
422
+ <label for="playback_pause">
423
+ <span><?php _e('Pause Duration:', 'easingslider'); ?></span>
424
+ <input type="number" name="playback_pause" id="playback_pause" value="<?php echo esc_attr($slider->playback_pause); ?>">
425
+ </label>
426
+ </div>
427
+ <p class="description"><?php _e('Sets the duration (in milliseconds) for the pause between slide transitions.', 'easingslider'); ?></p>
428
+ </div>
429
+
430
+ <?php
431
+ /**
432
+ * Allow for additional options
433
+ */
434
+ do_action('easingslider_playback_metabox_bottom', $slider);
435
+ ?>
436
+ </div>
437
+ </div>
438
+
439
+ <?php
440
+ /**
441
+ * Allow for additional boxes
442
+ */
443
+ do_action('easingslider_after_edit_slider_sidebar', $slider);
444
+ ?>
resources/views/list-sliders.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap">
2
+ <h2>
3
+ <?php _e('Sliders ', 'easingslider'); ?>
4
+ <a href="admin.php?page=easingslider-add-new" class="add-new-h2">
5
+ <?php _e('Add New', 'easingslider'); ?>
6
+ </a>
7
+
8
+ <?php if ( ! empty($_GET['s'])) : ?>
9
+ <span class="subtitle"><?php printf(__('Search results for &#8220;%s&#8221;', 'easingslider'), esc_attr($_GET['s'])); ?></span>
10
+ <?php endif; ?>
11
+ </h2>
12
+
13
+ <?php
14
+ /**
15
+ * Prepare the sliders list table items
16
+ */
17
+ $listTable->prepare_items();
18
+ ?>
19
+
20
+ <form id="sliders-list" method="get">
21
+ <input type="hidden" name="page" value="<?php echo esc_attr($page); ?>" />
22
+
23
+ <?php
24
+ /**
25
+ * Display a search input, allowing us to search through our sliders list.
26
+ */
27
+ $listTable->search_box(__('Search Sliders', 'easingslider'), 'search_id');
28
+
29
+ /**
30
+ * Display the available views
31
+ */
32
+ $listTable->views();
33
+
34
+ /**
35
+ * Display the list table
36
+ */
37
+ $listTable->display();
38
+ ?>
39
+ </form>
40
+ </div>
resources/views/view-addons.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap">
2
+ <h1>
3
+ <?php _e('Addons for Easing Slider', 'easingslider'); ?>
4
+ <a href="<?php echo esc_attr($addonsLink); ?>" class="page-title-action" target="_blank">
5
+ <?php _e('Browse All Addons', 'easingslider'); ?>
6
+ </a>
7
+ </h1>
8
+
9
+ <p><?php _e('These addons <em><strong>add functionality</strong></em> to Easing Slider.', 'easingslider'); ?></p>
10
+
11
+ <div class="license-entry <?php echo ('valid' == $license['status']) ? 'license-valid' : 'license-required'; ?>">
12
+ <form id="license" name="license" action="admin.php?page=<?php echo esc_attr($page); ?>" method="post">
13
+ <?php if ('valid' == $license['status']) : ?>
14
+ <p><strong><?php _e('Your license key:', 'easingslider' ); ?></strong></p>
15
+ <input type="hidden" name="easingslider_action" value="deactivate_license">
16
+ <span id="masked-key" class="masked-key"><?php echo esc_html($license->maskedKey()); ?></span>
17
+ <input type="submit" class="button-primary" value="<?php _e('Deactivate License', 'easingslider'); ?>">
18
+ <?php else : ?>
19
+ <p><?php printf(__('Enter your license key to gain access to addons. Don\'t have a license key? <a href="%s" target="_blank">Purchase one here</a>.', 'easingslider'), $purchaseLink); ?></p>
20
+ <input type="hidden" name="easingslider_action" value="activate_license">
21
+ <input type="text" id="license-key" name="license_key" value="<?php echo esc_attr($license['key']); ?>">
22
+ <input type="submit" class="button-primary" value="<?php _e('Activate License', 'easingslider'); ?>">
23
+ <?php endif; ?>
24
+ </form>
25
+ </div>
26
+
27
+ <?php if (false === $addons) : ?>
28
+ <div class="error">
29
+ <p><?php _e('There was an error retrieving the addons list from the server. Please try again later.', 'easingslider'); ?></p>
30
+ </div>
31
+ <?php else : ?>
32
+ <div class="addons">
33
+ <?php if ( ! empty($addons)) : ?>
34
+ <?php foreach ($addons as $addon) : ?>
35
+ <div class="addon">
36
+ <a href="<?php echo esc_attr($addon->link); ?>" title="<?php echo esc_attr($addon->title); ?>" class="addon-thumbnail">
37
+ <img src="<?php echo esc_attr($addon->image); ?>" class="attachment-showcase wp-post-image" alt="<?php echo esc_attr($addon->title); ?>" title="<?php echo esc_attr($addon->title); ?>" />
38
+ </a>
39
+
40
+ <h3 class="addon-title"><?php echo esc_html($addon->title); ?></h3>
41
+ <p class="addon-desc"><?php echo esc_attr($addon->content); ?></p>
42
+
43
+ <a href="<?php echo esc_attr($addon->link); ?>" target="_blank" title="<?php echo esc_attr($addon->title); ?>" class="addon-learn-more button-secondary"><?php _e('Learn More &rarr;', 'easingslider'); ?></a>
44
+
45
+ <?php if ('no_license' == $addon->status) : ?>
46
+ <div class="addon-status no-license">
47
+ <span class="status-message"><?php printf(__('Please <a href="%s" target="_blank">purchase a license</a> key to gain access.', 'easingslider'), $purchaseLink); ?></span>
48
+ </div>
49
+ <?php elseif ('upgrade_license' == $addon->status) : ?>
50
+ <div class="addon-status upgrade-license">
51
+ <span class="status-message"><?php _e('Upgrade license to gain access to this addon.', 'easingslider'); ?></span>
52
+ </div>
53
+ <?php elseif ('available' == $addon->status) : ?>
54
+ <?php if ($addon->slug) : ?>
55
+ <?php $addonBasename = easingslider_get_addon_basename($addon->slug); ?>
56
+
57
+ <?php if (is_plugin_active($addonBasename)) : ?>
58
+ <div class="addon-status is-active">
59
+ <span class="status-message"><?php _e('Status: Active', 'easingslider'); ?></span>
60
+ <a href="#" data-plugin="<?php echo esc_attr($addonBasename); ?>" class="addon-action button-primary js-deactivate-addon"><?php _e('Deactivate Addon', 'easingslider'); ?></a>
61
+ </div>
62
+ <?php elseif ( ! isset($installedPlugins[$addonBasename])) : ?>
63
+ <div class="addon-status not-installed">
64
+ <span class="status-message"><?php _e('Status: Not Installed', 'easingslider'); ?></span>
65
+ <a href="#" data-plugin="<?php echo esc_url($addon->download_link); ?>" class="addon-action button-primary js-install-addon"><?php _e('Install Addon', 'easingslider'); ?></a>
66
+ </div>
67
+ <?php elseif (is_plugin_inactive($addonBasename)) : ?>
68
+ <div class="addon-status is-inactive">
69
+ <span class="status-message"><?php _e('Status: Inactive', 'easingslider'); ?></span>
70
+ <a href="#" data-plugin="<?php echo esc_attr($addonBasename); ?>" class="addon-action button-primary js-activate-addon"><?php _e('Activate Addon', 'easingslider'); ?></a>
71
+ </div>
72
+ <?php endif; ?>
73
+ <?php else : ?>
74
+ <div class="addon-status">
75
+ <span><?php _e('Unavailable', 'easingslider'); ?></span>
76
+ </div>
77
+ <?php endif; ?>
78
+ <?php endif; ?>
79
+ </div>
80
+ <?php endforeach; ?>
81
+ <?php else : ?>
82
+ <h3><?php _e('Oops!', 'easingslider'); ?></h3>
83
+ <p><?php _e('Sorry, we couldn\'t retrieve the addons list. Instead, please view them on our website.', 'easingslider'); ?></p>
84
+ <a href="<?php echo esc_attr($addonsLink); ?>" class="button-secondary" target="_blank"><?php _e('Browse All Addons', 'easingslider'); ?></a>
85
+ <?php endif; ?>
86
+ </div>
87
+ <?php endif; ?>
88
+ </div>
src/Foundation/Activation/Activator.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Activation;
4
+
5
+ use EasingSlider\Foundation\Contracts\Activation\Activator as ActivatorContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Activator implements ActivatorContract
15
+ {
16
+ /**
17
+ * Executes activation
18
+ *
19
+ * @return void
20
+ */
21
+ abstract public function activate();
22
+ }
src/Foundation/Admin/Actions/Actions.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Actions;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Actions\Actions as ActionsContract;
6
+ use EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class Actions implements ActionsContract
16
+ {
17
+ /**
18
+ * Notices
19
+ *
20
+ * @var \EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler
21
+ */
22
+ protected $notices;
23
+
24
+ /**
25
+ * Constructor
26
+ *
27
+ * @param \EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler $notices
28
+ * @return void
29
+ */
30
+ public function __construct(NoticeHandler $notices)
31
+ {
32
+ $this->notices = $notices;
33
+
34
+ $this->defineActions();
35
+ }
36
+
37
+ /**
38
+ * Defines our actions
39
+ *
40
+ * @return void
41
+ */
42
+ abstract protected function defineActions();
43
+
44
+ /**
45
+ * Gets a new validator instance
46
+ *
47
+ * @return array
48
+ */
49
+ abstract protected function validator();
50
+ }
src/Foundation/Admin/Actions/Processor.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Actions;
4
+
5
+ use EasingSlider\Foundation\Admin\Admin;
6
+ use EasingSlider\Foundation\Contracts\Admin\Actions\Processor as ProcessorContract;
7
+ use EasingSlider\Foundation\Contracts\Plugin;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ abstract class Processor implements ProcessorContract
17
+ {
18
+ /**
19
+ * Actions
20
+ *
21
+ * @var array
22
+ */
23
+ protected $actions = array();
24
+
25
+ /**
26
+ * Plugin
27
+ *
28
+ * @var \EasingSlider\Foundation\Contracts\Plugin
29
+ */
30
+ protected $plugin;
31
+
32
+ /**
33
+ * Constructor
34
+ *
35
+ * @param \EasingSlider\Foundation\Contracts\Plugin $plugin
36
+ * @return void
37
+ */
38
+ public function __construct(Plugin $plugin)
39
+ {
40
+ $this->plugin = $plugin;
41
+
42
+ $this->defineHooks();
43
+
44
+ $this->boot();
45
+ }
46
+
47
+ /**
48
+ * Define hooks
49
+ *
50
+ * @return void
51
+ */
52
+ protected function defineHooks()
53
+ {
54
+ add_action('admin_init', array($this, 'process'));
55
+ }
56
+
57
+ /**
58
+ * Processes an action
59
+ *
60
+ * @return void
61
+ */
62
+ public function process()
63
+ {
64
+ if (isset($_POST['easingslider_action'])) {
65
+ do_action('easingslider_'. $_POST['easingslider_action'], $_POST);
66
+ }
67
+ elseif (isset($_GET['easingslider_action'])) {
68
+ do_action('easingslider_'. $_GET['easingslider_action'], $_GET);
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Checks if an offset exists
74
+ *
75
+ * @param mixed $offset
76
+ * @return boolean
77
+ */
78
+ public function offsetExists($offset)
79
+ {
80
+ return isset($this->actions[$offset]);
81
+ }
82
+
83
+ /**
84
+ * Gets an offset
85
+ *
86
+ * @param mixed $offset
87
+ * @return mixed
88
+ */
89
+ public function offsetGet($offset)
90
+ {
91
+ return $this->actions[$offset];
92
+ }
93
+
94
+ /**
95
+ * Sets a value
96
+ *
97
+ * @param mixed $offset
98
+ * @param mixed $value
99
+ * @return void
100
+ */
101
+ public function offsetSet($offset, $value)
102
+ {
103
+ $this->actions[$offset] = $value;
104
+ }
105
+
106
+ /**
107
+ * Unsets a value
108
+ *
109
+ * @param int $offset
110
+ * @return void
111
+ */
112
+ public function offsetUnset($offset)
113
+ {
114
+ unset($this->actions[$offset]);
115
+ }
116
+
117
+ /**
118
+ * Boot
119
+ *
120
+ * @return void
121
+ */
122
+ abstract protected function boot();
123
+ }
src/Foundation/Admin/Actions/ResourceActions.php ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Actions;
4
+
5
+ use EasingSlider\Foundation\Admin\Actions\Actions;
6
+ use EasingSlider\Foundation\Contracts\Admin\Actions\ResourceActions as ResourceActionsContract;
7
+ use EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler;
8
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
9
+
10
+ /**
11
+ * Exit if accessed directly
12
+ */
13
+ if ( ! defined('ABSPATH')) {
14
+ exit;
15
+ }
16
+
17
+ abstract class ResourceActions extends Actions implements ResourceActionsContract
18
+ {
19
+ /**
20
+ * Repository
21
+ *
22
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
23
+ */
24
+ protected $repository;
25
+
26
+ /**
27
+ * Action Suffix
28
+ *
29
+ * @var string
30
+ */
31
+ protected $actionSuffix;
32
+
33
+ /**
34
+ * Permissions
35
+ *
36
+ * @var array
37
+ */
38
+ protected $permissions;
39
+
40
+ /**
41
+ * Messages
42
+ *
43
+ * @var array
44
+ */
45
+ protected $messages;
46
+
47
+ /**
48
+ * Constructor
49
+ *
50
+ * @param \EasingSlider\Foundation\Contracts\Repositories\Repository $repository
51
+ * @param \EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler $notices
52
+ * @return void
53
+ */
54
+ public function __construct(Repository $repository, NoticeHandler $notices)
55
+ {
56
+ $this->repository = $repository;
57
+
58
+ $this->permissions = $this->getPermissions();
59
+ $this->messages = $this->getMessages();
60
+
61
+ parent::__construct($notices);
62
+ }
63
+
64
+ /**
65
+ * Defines our actions
66
+ *
67
+ * @return void
68
+ */
69
+ protected function defineActions()
70
+ {
71
+ add_action("easingslider_create_{$this->actionSuffix}", array($this, 'create'));
72
+ add_action("easingslider_update_{$this->actionSuffix}", array($this, 'update'));
73
+ add_action("easingslider_duplicate_{$this->actionSuffix}", array($this, 'duplicate'));
74
+ add_action("easingslider_trash_{$this->actionSuffix}", array($this, 'trash'));
75
+ add_action("easingslider_untrash_{$this->actionSuffix}", array($this, 'untrash'));
76
+ add_action("easingslider_delete_{$this->actionSuffix}", array($this, 'delete'));
77
+ }
78
+
79
+ /**
80
+ * Does necessary security checks
81
+ *
82
+ * @param string $referer
83
+ * @return boolean
84
+ */
85
+ protected function securityChecks($referer)
86
+ {
87
+ // Checks the admin referer, then do a permission check.
88
+ if (check_admin_referer($referer) && current_user_can($this->permissions[$referer])) {
89
+ return true;
90
+ }
91
+
92
+ return false;
93
+ }
94
+
95
+ /**
96
+ * Action for creating a resource
97
+ *
98
+ * @param array $data
99
+ * @return void
100
+ */
101
+ public function create($data = array())
102
+ {
103
+ if ($this->securityChecks('create')) {
104
+
105
+ // Validate the data
106
+ $data = $this->validator()->validate($data);
107
+
108
+ // Create the model
109
+ $model = $this->repository->create($data);
110
+
111
+ // Redirect to the editor after creating the new resource
112
+ $this->creationRedirect($model->ID);
113
+
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Action for updating a resource
119
+ *
120
+ * @param array $data
121
+ * @return void
122
+ */
123
+ public function update($data = array())
124
+ {
125
+ if ($this->securityChecks('update')) {
126
+
127
+ // Validate the data
128
+ $data = $this->validator()->validate($data);
129
+
130
+ // Update the model
131
+ $this->repository->update($data['id'], $data);
132
+
133
+ // Tell the user
134
+ $this->notices->success("{$this->actionSuffix}_updated", $this->messages['updated']);
135
+
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Action for duplicating a resource
141
+ *
142
+ * @param array $data
143
+ * @return void
144
+ */
145
+ public function duplicate($data = array())
146
+ {
147
+ if ($this->securityChecks('duplicate')) {
148
+
149
+ // Validate the data
150
+ $data = $this->validator()->validate($data);
151
+
152
+ // Duplicate the model
153
+ $this->repository->duplicate($data['id']);
154
+
155
+ // Tell the user
156
+ $this->notices->success("{$this->actionSuffix}_duplicated", $this->messages['duplicated']);
157
+
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Action for trash a resource
163
+ *
164
+ * @param array $data
165
+ * @return void
166
+ */
167
+ public function trash($data = array())
168
+ {
169
+ if ($this->securityChecks('trash')) {
170
+
171
+ // Validate the data
172
+ $data = $this->validator()->validate($data);
173
+
174
+ // Trash the model
175
+ $this->repository->trash($data['id']);
176
+
177
+ // Tell the user
178
+ $this->notices->success("{$this->actionSuffix}_trashed", $this->messages['trashed']);
179
+
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Action for untrashing a resource
185
+ *
186
+ * @param array $data
187
+ * @return void
188
+ */
189
+ public function untrash($data = array())
190
+ {
191
+ if ($this->securityChecks('untrash')) {
192
+
193
+ // Validate the data
194
+ $data = $this->validator()->validate($data);
195
+
196
+ // Untrash the model
197
+ $this->repository->untrash($data['id']);
198
+
199
+ // Tell the user
200
+ $this->notices->success("{$this->actionSuffix}_untrashed", $this->messages['untrashed']);
201
+
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Action for deleting a resource
207
+ *
208
+ * @param array $data
209
+ * @return void
210
+ */
211
+ public function delete($data = array())
212
+ {
213
+ if ($this->securityChecks('delete')) {
214
+
215
+ // Validate the data
216
+ $data = $this->validator()->validate($data);
217
+
218
+ // Delete the model
219
+ $this->repository->delete($data['id']);
220
+
221
+ // Tell the user
222
+ $this->notices->success("{$this->actionSuffix}_deleted", $this->messages['deleted']);
223
+
224
+ }
225
+ }
226
+ /**
227
+ * Gets the permissions for our security checks
228
+ *
229
+ * @return array
230
+ */
231
+ abstract protected function getPermissions();
232
+
233
+ /**
234
+ * Gets the messages for our notices
235
+ *
236
+ * @return array
237
+ */
238
+ abstract protected function getMessages();
239
+
240
+ /**
241
+ * Redirects to the resource editor after creation
242
+ *
243
+ * @param int $id
244
+ * @return void
245
+ */
246
+ abstract protected function creationRedirect($id);
247
+ }
src/Foundation/Admin/Admin.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Admin as AdminContract;
6
+ use EasingSlider\Foundation\Contracts\Plugin;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class Admin implements AdminContract
16
+ {
17
+ /**
18
+ * Plugin
19
+ *
20
+ * @var \EasingSlider\Foundation\Contracts\Plugin
21
+ */
22
+ protected $plugin;
23
+
24
+ /**
25
+ * Admin Prefix
26
+ *
27
+ * @var string
28
+ */
29
+ protected $prefix;
30
+
31
+ /**
32
+ * Services
33
+ *
34
+ * @var array
35
+ */
36
+ protected $services = array();
37
+
38
+ /**
39
+ * Constructor
40
+ *
41
+ * @param \EasingSlider\Foundation\Contracts\Plugin $plugin
42
+ * @return void
43
+ */
44
+ public function __construct(Plugin $plugin)
45
+ {
46
+ $this->plugin = $plugin;
47
+
48
+ $this->bindAliases();
49
+
50
+ $this->bindSingletons();
51
+
52
+ $this->boot();
53
+ }
54
+
55
+ /**
56
+ * __call function.
57
+ *
58
+ * @param string $name
59
+ * @param array $arguments
60
+ * @return mixed
61
+ */
62
+ public function __call($name, $arguments)
63
+ {
64
+ if (isset($this->$name)) {
65
+ return $this->$name;
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Bind aliases
71
+ *
72
+ * @return void
73
+ */
74
+ protected function bindAliases()
75
+ {
76
+ foreach ($this->aliases as $contract => $class) {
77
+ $this->plugin->alias($contract, $class);
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Bind singletons
83
+ *
84
+ * @return void
85
+ */
86
+ protected function bindSingletons()
87
+ {
88
+ foreach ($this->singletons as $singleton) {
89
+ $this->plugin->share($singleton);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Boot
95
+ *
96
+ * @return void
97
+ */
98
+ abstract protected function boot();
99
+ }
src/Foundation/Admin/Ajax/Router.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Ajax;
4
+
5
+ use EasingSlider\Foundation\Admin\Admin;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Router
15
+ {
16
+ /**
17
+ * Constructor
18
+ *
19
+ * @return void
20
+ */
21
+ public function __construct()
22
+ {
23
+ $this->defineHooks();
24
+ }
25
+
26
+ /**
27
+ * Define hooks
28
+ *
29
+ * @return void
30
+ */
31
+ abstract protected function defineHooks();
32
+
33
+ /**
34
+ * Sets an ajax route action
35
+ *
36
+ * @param string $action
37
+ * @param string|array $callback
38
+ * @param boolean $requiresAuth
39
+ * @return void
40
+ */
41
+ public function setAction($action, $callback, $requiresAuth = true)
42
+ {
43
+ add_action("wp_ajax_{$action}", $callback);
44
+
45
+ if (false === $requiresAuth) {
46
+ add_action("wp_ajax_nopriv_{$action}", $callback);
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Provides a response
52
+ *
53
+ * @param mixed $data
54
+ * @return void
55
+ */
56
+ protected function response($data)
57
+ {
58
+ echo json_encode($data);
59
+ die();
60
+ }
61
+ }
src/Foundation/Admin/Assets/Assets.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Assets;
4
+
5
+ use EasingSlider\Foundation\Assets\Assets as BaseAssets;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Assets extends BaseAssets
15
+ {
16
+ //
17
+ }
src/Foundation/Admin/LicenseHandlers/EDDLicenseHandler.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\LicenseHandlers;
4
+
5
+ use EasingSlider\Foundation\Admin\LicenseHandlers\LicenseHandler;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class EDDLicenseHandler extends LicenseHandler
15
+ {
16
+ /**
17
+ * Provides a response object
18
+ *
19
+ * @param object|WP_Error $response
20
+ * @return object
21
+ */
22
+ protected function response($response)
23
+ {
24
+ // Check for WordPress errors
25
+ if (is_wp_error($response)) {
26
+ return $this->errorResponse(
27
+ $response->get_error_message()
28
+ );
29
+ }
30
+
31
+ // Get response body
32
+ $data = json_decode(wp_remote_retrieve_body($response));
33
+
34
+ // Check we received a response body
35
+ if (is_null($data)) {
36
+ return $this->errorResponse(
37
+ __('Failed to connect to API. No response provided. Please contact support.', 'easingslider')
38
+ );
39
+ }
40
+
41
+ // Check for errors
42
+ if (isset($data->error)) {
43
+ return $this->errorResponse(
44
+ $this->getErrorMessage($data)
45
+ );
46
+ }
47
+
48
+ // Check for success
49
+ if (isset($data->success)) {
50
+ return $this->successResponse(
51
+ $this->getSuccessMessage($data)
52
+ );
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Gets the appropriate success message
58
+ *
59
+ * @param object $data
60
+ * @return string
61
+ */
62
+ protected function getSuccessMessage($data)
63
+ {
64
+ switch ($data->license) {
65
+ case 'valid':
66
+ $message = __('License has been activated successfully.', 'easingslider');
67
+ break;
68
+
69
+ case 'deactivated':
70
+ $message = __('License has been deactivated successfully.', 'easingslider');
71
+ break;
72
+ }
73
+
74
+ return apply_filters('easingslider_edd_license_handler_success_response', $message, $data);
75
+ }
76
+
77
+ /**
78
+ * Gets the appropriate success message
79
+ *
80
+ * @param object $data
81
+ * @return string
82
+ */
83
+ protected function getErrorMessage($data)
84
+ {
85
+ switch ($data->error) {
86
+ case 'expired':
87
+ $message = sprintf(__('Your license key has expired on %s. Please renew your license key.', 'easingslider'), date_i18n(get_option('date_format'), strtotime($data->expires)));
88
+ break;
89
+
90
+ case 'invalid_item_id':
91
+ $message = __('An invalid item ID has been provided. Please contact support.', 'easingslider');
92
+ break;
93
+
94
+ case 'item_name_mismatch':
95
+ $message = __('The license key entered is not a valid license key for this plugin.', 'easingslider');
96
+ break;
97
+
98
+ case 'license_not_activable':
99
+ $message = __('The license key provided is a "bundle" license key. Bundle license keys cannot be activated.', 'easingslider');
100
+ break;
101
+
102
+ case 'missing':
103
+ $message = __('The license key you have entered does not exist.', 'easingslider');
104
+ break;
105
+
106
+ case 'no_activations_left':
107
+ $message = sprinft(__('Your license key has reached its activation limit of %d. Please upgrade your license key to get more activations.', 'easingslider'), $data->max_sites);
108
+ break;
109
+
110
+ case 'revoked':
111
+ $message = __('Your license key has been revoked. Please contact support.', 'easingslider');
112
+ break;
113
+
114
+ default:
115
+ $message = __('An unknown error occurred. Please contact support.', 'easingslider');
116
+ break;
117
+ }
118
+
119
+ return apply_filters('easingslider_edd_license_handler_error_response', $message, $data);
120
+ }
121
+
122
+ /**
123
+ * Checks if a license is valid
124
+ *
125
+ * @return boolean
126
+ */
127
+ public function isValid()
128
+ {
129
+ $requestParams = array(
130
+ 'edd_action' => 'check_license',
131
+ 'license' => $this->getKey(),
132
+ 'item_name' => urlencode($this->name)
133
+ );
134
+
135
+ // Get the request URL
136
+ $requestUrl = add_query_arg($requestParams, $this->getApiUrl());
137
+
138
+ // Get response from API
139
+ $response = wp_remote_get(
140
+ $requestUrl,
141
+ array(
142
+ 'timeout' => 15,
143
+ 'sslverify' => false
144
+ )
145
+ );
146
+
147
+ // Check for errors
148
+ if (is_wp_error($response)) {
149
+ return false;
150
+ }
151
+
152
+ // Get license data
153
+ $data = json_decode(wp_remote_retrieve_body($response));
154
+
155
+ // Check license is valid
156
+ if ($data && 'valid' == $data->license) {
157
+ return true;
158
+ }
159
+
160
+ return false;
161
+ }
162
+
163
+ /**
164
+ * Activates the license key
165
+ *
166
+ * @return object
167
+ */
168
+ public function activate()
169
+ {
170
+ $requestParams = array(
171
+ 'edd_action' => 'activate_license',
172
+ 'license' => $this->getKey(),
173
+ 'item_name' => urlencode($this->name),
174
+ 'url' => home_url()
175
+ );
176
+
177
+ // Get response from API
178
+ $response = wp_remote_post(
179
+ $this->getApiUrl(),
180
+ array(
181
+ 'timeout' => 15,
182
+ 'sslverify' => false,
183
+ 'body' => $requestParams
184
+ )
185
+ );
186
+
187
+ return $this->response($response);
188
+ }
189
+
190
+ /**
191
+ * Deactivates the license key
192
+ *
193
+ * @return object
194
+ */
195
+ public function deactivate()
196
+ {
197
+ $requestParams = array(
198
+ 'edd_action' => 'deactivate_license',
199
+ 'license' => $this->getKey(),
200
+ 'item_name' => urlencode($this->name),
201
+ 'url' => home_url()
202
+ );
203
+
204
+ // Get response from API
205
+ $response = wp_remote_post(
206
+ $this->getApiUrl(),
207
+ array(
208
+ 'timeout' => 15,
209
+ 'sslverify' => false,
210
+ 'body' => $requestParams
211
+ )
212
+ );
213
+
214
+ return $this->response($response);
215
+ }
216
+ }
src/Foundation/Admin/LicenseHandlers/LicenseHandler.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\LicenseHandlers;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\LicenseHandlers\LicenseHandler as LicenseHandlerContract;
6
+ use EasingSlider\Foundation\Contracts\Options\OptionArray;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class LicenseHandler implements LicenseHandlerContract
16
+ {
17
+ /**
18
+ * License
19
+ *
20
+ * @var \EasingSlider\Foundation\Contracts\Options\OptionArray
21
+ */
22
+ protected $license;
23
+
24
+ /**
25
+ * Name
26
+ *
27
+ * @var string
28
+ */
29
+ protected $name;
30
+
31
+ /**
32
+ * File
33
+ *
34
+ * @var string
35
+ */
36
+ protected $file;
37
+
38
+ /**
39
+ * Version
40
+ *
41
+ * @var string
42
+ */
43
+ protected $version;
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @param \EasingSlider\Foundation\Contracts\Options\OptionArray $license
49
+ * @param string $name
50
+ * @param string $file
51
+ * @param string $version
52
+ * @return void
53
+ */
54
+ public function __construct(OptionArray $license, $name, $file, $version)
55
+ {
56
+ $this->name = $name;
57
+ $this->file = $file;
58
+ $this->version = $version;
59
+ $this->license = $license;
60
+ }
61
+
62
+ /**
63
+ * Provides a success response
64
+ *
65
+ * @param string $message
66
+ * @return object
67
+ */
68
+ protected function successResponse($message)
69
+ {
70
+ return (object) array(
71
+ 'success' => true,
72
+ 'message' => $message
73
+ );
74
+ }
75
+
76
+ /**
77
+ * Provides an error response
78
+ *
79
+ * @param string $message
80
+ * @return object
81
+ */
82
+ protected function errorResponse($message)
83
+ {
84
+ return (object) array(
85
+ 'error' => true,
86
+ 'message' => $message
87
+ );
88
+ }
89
+
90
+ /**
91
+ * Gets the API URL
92
+ *
93
+ * @return string
94
+ */
95
+ protected function getApiUrl()
96
+ {
97
+ return easingslider_api_url();
98
+ }
99
+
100
+ /**
101
+ * Gets the license key
102
+ *
103
+ * @return string
104
+ */
105
+ public function getKey()
106
+ {
107
+ return $this->license['key'];
108
+ }
109
+
110
+ /**
111
+ * Sets the license key
112
+ *
113
+ * @param string $key
114
+ * @return void
115
+ */
116
+ public function setKey($key)
117
+ {
118
+ $this->license['key'] = $key;
119
+ $this->license->save();
120
+ }
121
+
122
+ /**
123
+ * Sets the license status
124
+ *
125
+ * @param string $status
126
+ * @return void
127
+ */
128
+ public function setStatus($status)
129
+ {
130
+ $this->license['status'] = $status;
131
+ $this->license->save();
132
+ }
133
+
134
+ /**
135
+ * Checks if a license is valid
136
+ *
137
+ * @return boolean
138
+ */
139
+ abstract public function isValid();
140
+
141
+ /**
142
+ * Activates the license key
143
+ *
144
+ * @return object
145
+ */
146
+ abstract public function activate();
147
+
148
+ /**
149
+ * Deactivates the license key
150
+ *
151
+ * @return object
152
+ */
153
+ abstract public function deactivate();
154
+ }
src/Foundation/Admin/ListTables/ListTable.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\ListTables;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\ListTables\ListTable as ListTableContract;
6
+ use WP_List_Table;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Ensure WP_List_Table class has been loaded
17
+ */
18
+ if ( ! class_exists( 'WP_List_Table' ) ) {
19
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
20
+ }
21
+
22
+ abstract class ListTable extends WP_List_Table implements ListTableContract
23
+ {
24
+ //
25
+ }
src/Foundation/Admin/Menus/Menu.php ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Menus;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Menus\Menu as MenuContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Menu implements MenuContract
15
+ {
16
+ /**
17
+ * Page Title
18
+ *
19
+ * @var string
20
+ */
21
+ protected $pageTitle;
22
+
23
+ /**
24
+ * Menu Title
25
+ *
26
+ * @var string
27
+ */
28
+ protected $menuTitle;
29
+
30
+ /**
31
+ * Capability
32
+ *
33
+ * @var string
34
+ */
35
+ protected $capability;
36
+
37
+ /**
38
+ * Menu Slug
39
+ *
40
+ * @var string
41
+ */
42
+ protected $menuSlug;
43
+
44
+ /**
45
+ * Function
46
+ *
47
+ * @var string|array|null
48
+ */
49
+ protected $function = null;
50
+
51
+ /**
52
+ * Icon Url
53
+ *
54
+ * @var string
55
+ */
56
+ protected $iconUrl = '';
57
+
58
+ /**
59
+ * Submenus
60
+ *
61
+ * @var array
62
+ */
63
+ public $submenus = array();
64
+
65
+ /**
66
+ * Constructor
67
+ *
68
+ * @return void
69
+ */
70
+ public function __construct()
71
+ {
72
+ $this->defineHooks();
73
+ }
74
+
75
+ /**
76
+ * Define hooks
77
+ *
78
+ * @return void
79
+ */
80
+ public function defineHooks()
81
+ {
82
+ add_action('admin_menu', array($this, 'setupMenu'));
83
+ }
84
+
85
+ /**
86
+ * Sets the toplevel menu
87
+ *
88
+ * @param string $pageTitle
89
+ * @param string $menuTitle
90
+ * @param string $capability
91
+ * @param string $menuSlug
92
+ * @param string|array|null $function
93
+ * @param string $iconUrl
94
+ * @return void
95
+ */
96
+ public function setToplevelMenu($pageTitle, $menuTitle, $capability, $menuSlug, $function = null, $iconUrl = '')
97
+ {
98
+ // Get toplevel position
99
+ $position = $this->getToplevelPosition();
100
+
101
+ // Set variables
102
+ $this->pageTitle = $pageTitle;
103
+ $this->menuTitle = $menuTitle;
104
+ $this->capability = $capability;
105
+ $this->menuSlug = $menuSlug;
106
+ $this->function = $function;
107
+ $this->iconUrl = $iconUrl;
108
+
109
+ // Add the toplevel menu
110
+ add_menu_page(
111
+ $this->pageTitle,
112
+ $this->menuTitle,
113
+ $this->capability,
114
+ $this->menuSlug,
115
+ $this->function,
116
+ $this->iconUrl,
117
+ "{$position}"
118
+ );
119
+ }
120
+
121
+ /**
122
+ * Adds a submenu page
123
+ *
124
+ * @param string $pageTitle
125
+ * @param string $menuTitle
126
+ * @param string $capability
127
+ * @param string $menuSlug
128
+ * @param string|array|null $callable
129
+ * @return void
130
+ */
131
+ public function addSubmenuPage($pageTitle, $menuTitle, $capability, $menuSlug, $callable = null)
132
+ {
133
+ // Add submenu page
134
+ $this->submenus[] = add_submenu_page(
135
+ $this->menuSlug,
136
+ $pageTitle,
137
+ $menuTitle,
138
+ $capability,
139
+ $menuSlug,
140
+ $callable
141
+ );
142
+ }
143
+
144
+ /**
145
+ * Gets a suitable toplevel menu position
146
+ *
147
+ * @return string
148
+ */
149
+ protected function getToplevelPosition()
150
+ {
151
+ global $menu;
152
+
153
+ // Default menu positioning
154
+ $position = '100.1';
155
+
156
+ // If enabled, relocate the plugin menus higher
157
+ if (apply_filters('easingslider_relocate_menus', __return_true())) {
158
+
159
+ for ($position = '40.1'; $position <= '100.1'; $position += '0.1') {
160
+
161
+ // Ensure there is a space before and after each position we are checking, leaving room for our separators.
162
+ $before = $position - '0.1';
163
+ $after = $position + '0.1';
164
+
165
+ // Do the checks for each position. These need to be strings, hence the quotation marks.
166
+ if (isset($menu["$position"])) {
167
+ continue;
168
+ }
169
+ if (isset($menu["$before" ])) {
170
+ continue;
171
+ }
172
+ if (isset($menu["$after" ])) {
173
+ continue;
174
+ }
175
+
176
+ // If we've successfully gotten this far, break the loop. We've found the position we need.
177
+ break;
178
+
179
+ }
180
+
181
+ // Add the menu separators
182
+ $this->addSeparator("$before");
183
+ $this->addSeparator("$after");
184
+
185
+ }
186
+
187
+ return $position;
188
+ }
189
+
190
+ /**
191
+ * Create a separator in the admin menus, above and below our plugin menus
192
+ *
193
+ * @param string $position The menu position to insert the separator
194
+ * @return void
195
+ */
196
+ protected function addSeparator($position = '40.1')
197
+ {
198
+ global $menu;
199
+
200
+ // Set index as 0
201
+ $index = 0;
202
+
203
+ // Loop through each menu item
204
+ foreach ($menu as $offset => $section) {
205
+
206
+ // Increment if we find a separate already at this position
207
+ if ('separator' == substr($section[2], 0, 9)) {
208
+ $index++;
209
+ }
210
+
211
+ // Add our separator
212
+ if ($offset >= $position) {
213
+
214
+ // Quotation marks ensures the position is a string. Integers won't work if we are using decimal values.
215
+ $menu[ "$position" ] = array( '', 'read', "separator{$index}", '', 'wp-menu-separator' );
216
+ break;
217
+
218
+ }
219
+
220
+ }
221
+
222
+ // Sort the menu
223
+ ksort($menu);
224
+ }
225
+
226
+ /**
227
+ * Setup menu
228
+ *
229
+ * @return void
230
+ */
231
+ abstract public function setupMenu();
232
+ }
src/Foundation/Admin/Notices/ErrorNotice.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Notices;
4
+
5
+ use EasingSlider\Foundation\Admin\Notices\Notice;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class ErrorNotice extends Notice
15
+ {
16
+ /**
17
+ * Provides the notice class names
18
+ *
19
+ * @return array
20
+ */
21
+ protected function classNames()
22
+ {
23
+ return array('message', 'error');
24
+ }
25
+ }
src/Foundation/Admin/Notices/InfoNotice.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Notices;
4
+
5
+ use EasingSlider\Foundation\Admin\Notices\Notice;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class InfoNotice extends Notice
15
+ {
16
+ /**
17
+ * Provides the notice class names
18
+ *
19
+ * @return array
20
+ */
21
+ protected function classNames()
22
+ {
23
+ return array('message', 'updated', 'notice');
24
+ }
25
+ }
src/Foundation/Admin/Notices/Notice.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Notices;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Notices\Notice as NoticeContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Notice implements NoticeContract
15
+ {
16
+ /**
17
+ * Handle
18
+ *
19
+ * @var string
20
+ */
21
+ protected $handle;
22
+
23
+ /**
24
+ * Message
25
+ *
26
+ * @var string
27
+ */
28
+ protected $message;
29
+
30
+ /**
31
+ * Constructor
32
+ *
33
+ * @param string $handle
34
+ * @param string $message
35
+ * @return void
36
+ */
37
+ public function __construct($handle, $message)
38
+ {
39
+ $this->handle = $handle;
40
+ $this->message = $message;
41
+ }
42
+
43
+ /**
44
+ * Gets the notice class names
45
+ *
46
+ * @return string
47
+ */
48
+ protected function getClassNames()
49
+ {
50
+ return implode(' ', $this->classNames());
51
+ }
52
+
53
+ /**
54
+ * Displays the notice
55
+ *
56
+ * @return void
57
+ */
58
+ public function display()
59
+ {
60
+ $classNames = $this->getClassNames();
61
+
62
+ ?>
63
+ <div class="<?php echo esc_attr($classNames); ?>">
64
+ <p><?php echo wp_kses_post($this->message); ?></p>
65
+ </div>
66
+ <?php
67
+ }
68
+
69
+ /**
70
+ * Provides the notice class names
71
+ *
72
+ * @return array
73
+ */
74
+ abstract protected function classNames();
75
+ }
src/Foundation/Admin/Notices/NoticeHandler.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Notices;
4
+
5
+ use EasingSlider\Foundation\Admin\Notices\ErrorNotice;
6
+ use EasingSlider\Foundation\Admin\Notices\InfoNotice;
7
+ use EasingSlider\Foundation\Admin\Notices\SuccessNotice;
8
+ use EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler as NoticeHandlerContract;
9
+ use EasingSlider\Foundation\Contracts\Admin\Notices\Notice;
10
+
11
+ /**
12
+ * Exit if accessed directly
13
+ */
14
+ if ( ! defined('ABSPATH')) {
15
+ exit;
16
+ }
17
+
18
+ class NoticeHandler implements NoticeHandlerContract
19
+ {
20
+ /**
21
+ * Notices
22
+ *
23
+ * @var array
24
+ */
25
+ protected $notices = array();
26
+
27
+ /**
28
+ * Constructor
29
+ *
30
+ * @return void
31
+ */
32
+ public function __construct()
33
+ {
34
+ $this->defineHooks();
35
+ }
36
+
37
+ /**
38
+ * Define hooks
39
+ *
40
+ * @return void
41
+ */
42
+ protected function defineHooks()
43
+ {
44
+ add_action('admin_notices', array($this, 'displayNotices'));
45
+ }
46
+
47
+ /**
48
+ * Displays the notices
49
+ *
50
+ * @return void
51
+ */
52
+ public function displayNotices()
53
+ {
54
+ foreach ($this->notices as $notice)
55
+ {
56
+ $notice->display();
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Pushes a notice
62
+ *
63
+ * @param string $type
64
+ * @param string $handle
65
+ * @param string $message
66
+ * @return void
67
+ */
68
+ protected function pushNotice($type, $handle, $message)
69
+ {
70
+ switch ($type) {
71
+ case 'error':
72
+ $notice = new ErrorNotice($handle, $message);
73
+ break;
74
+
75
+ case 'info':
76
+ $notice = new InfoNotice($handle, $message);
77
+ break;
78
+
79
+ case 'success':
80
+ $notice = new SuccessNotice($handle, $message);
81
+ break;
82
+ }
83
+
84
+ if (isset($notice)) {
85
+ $this->notices[] = $notice;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Shows a success notice
91
+ *
92
+ * @param string $handle
93
+ * @param string $message
94
+ * @return void
95
+ */
96
+ public function success($handle, $message)
97
+ {
98
+ $this->pushNotice('success', $handle, $message);
99
+ }
100
+
101
+ /**
102
+ * Shows an error notice
103
+ *
104
+ * @param string $handle
105
+ * @param string $message
106
+ * @return void
107
+ */
108
+ public function error($handle, $message)
109
+ {
110
+ $this->pushNotice('error', $handle, $message);
111
+ }
112
+
113
+ /**
114
+ * Shows an info notice
115
+ *
116
+ * @param string $handle
117
+ * @param string $message
118
+ * @return void
119
+ */
120
+ public function info($handle, $message)
121
+ {
122
+ $this->pushNotice('info', $handle, $message);
123
+ }
124
+ }
src/Foundation/Admin/Notices/SuccessNotice.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Notices;
4
+
5
+ use EasingSlider\Foundation\Admin\Notices\Notice;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class SuccessNotice extends Notice
15
+ {
16
+ /**
17
+ * Provides the notice class names
18
+ *
19
+ * @return array
20
+ */
21
+ protected function classNames()
22
+ {
23
+ return array('message', 'updated');
24
+ }
25
+ }
src/Foundation/Admin/Panels/Panel.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Panels\Panel as PanelContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Panel implements PanelContract
15
+ {
16
+ /**
17
+ * Gets a parameter from the URL
18
+ *
19
+ * @param string $param
20
+ * @return string|false
21
+ */
22
+ protected function getUrlParam($param)
23
+ {
24
+ if ( ! empty($_GET[$param])) {
25
+ return $_GET[$param];
26
+ }
27
+
28
+ return false;
29
+ }
30
+
31
+ /**
32
+ * Gets the page slug
33
+ *
34
+ * @return string|false
35
+ */
36
+ protected function getPage()
37
+ {
38
+ return $this->getUrlParam('page');
39
+ }
40
+
41
+ /**
42
+ * Gets the page ID
43
+ *
44
+ * @return string|false
45
+ */
46
+ protected function getID()
47
+ {
48
+ return $this->getUrlParam('edit');
49
+ }
50
+
51
+ /**
52
+ * Shows a view
53
+ *
54
+ * @param string $view
55
+ * @param array $data
56
+ * @return void
57
+ */
58
+ protected function showView($view, $data = array())
59
+ {
60
+ extract($data);
61
+
62
+ require EASINGSLIDER_RESOURCES_DIR .'views/'. $view .'.php';
63
+ }
64
+
65
+ /**
66
+ * Displays the panel
67
+ *
68
+ * @return void
69
+ */
70
+ abstract public function display();
71
+ }
src/Foundation/Admin/Panels/Panels.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Panels;
4
+
5
+ use ArrayAccess;
6
+ use EasingSlider\Foundation\Contracts\Admin\Panels\Panels as PanelsContract;
7
+ use EasingSlider\Foundation\Contracts\Plugin;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ abstract class Panels implements PanelsContract, ArrayAccess
17
+ {
18
+ /**
19
+ * Panels
20
+ *
21
+ * @var array
22
+ */
23
+ protected $panels = array();
24
+
25
+ /**
26
+ * Plugin
27
+ *
28
+ * @var \EasingSlider\Foundation\Contracts\Plugin
29
+ */
30
+ protected $plugin;
31
+
32
+ /**
33
+ * Constructor
34
+ *
35
+ * @param \EasingSlider\Foundation\Contracts\Plugin $plugin
36
+ * @return void
37
+ */
38
+ public function __construct(Plugin $plugin)
39
+ {
40
+ $this->plugin = $plugin;
41
+
42
+ $this->defineHooks();
43
+
44
+ $this->boot();
45
+ }
46
+
47
+ /**
48
+ * Checks if an offset exists
49
+ *
50
+ * @param mixed $offset
51
+ * @return boolean
52
+ */
53
+ public function offsetExists($offset)
54
+ {
55
+ return isset($this->panels[$offset]);
56
+ }
57
+
58
+ /**
59
+ * Gets an offset
60
+ *
61
+ * @param mixed $offset
62
+ * @return mixed
63
+ */
64
+ public function offsetGet($offset)
65
+ {
66
+ return $this->panels[$offset];
67
+ }
68
+
69
+ /**
70
+ * Sets a value
71
+ *
72
+ * @param mixed $offset
73
+ * @param mixed $value
74
+ * @return void
75
+ */
76
+ public function offsetSet($offset, $value)
77
+ {
78
+ $this->panels[$offset] = $value;
79
+ }
80
+
81
+ /**
82
+ * Unsets a value
83
+ *
84
+ * @param int $offset
85
+ * @return void
86
+ */
87
+ public function offsetUnset($offset)
88
+ {
89
+ unset($this->panels[$offset]);
90
+ }
91
+
92
+ /**
93
+ * Define hooks
94
+ *
95
+ * @return void
96
+ */
97
+ protected function defineHooks()
98
+ {
99
+ if (method_exists($this, 'getFooterText')) {
100
+ add_action('admin_footer_text', array($this, 'modifyFooterText'));
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Modifies the plugin footer text with a custom message (optionally).
106
+ *
107
+ * @param string $footerText
108
+ * @return string
109
+ */
110
+ public function modifyFooterText($footerText)
111
+ {
112
+ //
113
+ }
114
+
115
+ /**
116
+ * Boot
117
+ *
118
+ * @return void
119
+ */
120
+ abstract protected function boot();
121
+ }
src/Foundation/Admin/Panels/SettingsApiPanel.php ADDED
@@ -0,0 +1,428 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Admin\Panels\Panel;
6
+ use EasingSlider\Foundation\Contracts\Admin\Panels\Panel as PanelContract;
7
+ use EasingSlider\Foundation\Contracts\Options\OptionArray;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ abstract class SettingsApiPanel extends Panel implements PanelContract
17
+ {
18
+ /**
19
+ * Option
20
+ *
21
+ * @var \EasingSlider\Foundation\Contracts\Options\OptionArray
22
+ */
23
+ protected $option;
24
+
25
+ /**
26
+ * Page Slug
27
+ *
28
+ * @var string|false
29
+ */
30
+ protected $page;
31
+
32
+ /**
33
+ * Constructor
34
+ *
35
+ * @param \EasingSlider\Foundation\Contracts\Options\OptionArray $option
36
+ * @return array
37
+ */
38
+ public function __construct(OptionArray $option)
39
+ {
40
+ $this->option = $option;
41
+
42
+ // Get the page slug
43
+ $this->page = $this->getPage();
44
+
45
+ // Define hooks
46
+ $this->defineHooks();
47
+ }
48
+
49
+ /**
50
+ * Define hooks
51
+ *
52
+ * @return void
53
+ */
54
+ protected function defineHooks()
55
+ {
56
+ add_action('admin_init', array($this, 'registerFields'));
57
+ }
58
+
59
+ /**
60
+ * Gets the page slug
61
+ *
62
+ * @return string
63
+ */
64
+ protected function getPage()
65
+ {
66
+ if ( ! empty($_GET['page'])) {
67
+ return $_GET['page'];
68
+ }
69
+
70
+ return false;
71
+ }
72
+
73
+ /**
74
+ * Registers the settings fields
75
+ *
76
+ * @return void
77
+ */
78
+ public function registerFields()
79
+ {
80
+ $optionName = $this->option->getName();
81
+
82
+ // Loop through settings sections
83
+ foreach ($this->getSections() as $tab => $settings) {
84
+
85
+ // Add the section
86
+ add_settings_section("{$optionName}_{$tab}", __return_null(), '__return_false', "{$optionName}_{$tab}");
87
+
88
+ // Loop through settings fields
89
+ foreach ($settings as $key => $option) {
90
+
91
+ // Add the field
92
+ add_settings_field(
93
+ "{$optionName}[{$key}]",
94
+ isset($option['name']) ? $option['name'] : '',
95
+ is_callable(array($this, $option['type'] . 'Callback')) ? array($this, $option['type'] . 'Callback') : array($this, 'missingCallback'),
96
+ "{$optionName}_{$tab}",
97
+ "{$optionName}_{$tab}",
98
+ array(
99
+ 'id' => $key,
100
+ 'desc' => ! empty($option['desc']) ? $option['desc'] : '',
101
+ 'name' => isset($option['name']) ? $option['name'] : null,
102
+ 'section' => $tab,
103
+ 'label' => isset($option['label']) ? $option['label'] : null,
104
+ 'action' => isset($option['action']) ? $option['action'] : null,
105
+ 'size' => isset($option['size']) ? $option['size'] : 'regular',
106
+ 'max' => isset($option['max']) ? $option['max'] : 999999,
107
+ 'min' => isset($option['min']) ? $option['min'] : 0,
108
+ 'step' => isset($option['step']) ? $option['step'] : 1,
109
+ 'options' => isset($option['options']) ? $option['options'] : '',
110
+ 'std' => isset($option['std']) ? $option['std'] : ''
111
+ )
112
+ );
113
+
114
+ }
115
+
116
+ }
117
+
118
+ // Creates the settings in the options table
119
+ register_setting($optionName, $optionName, array($this, 'sanitizeInput'));
120
+ }
121
+
122
+ /**
123
+ * Validates the settings input
124
+ *
125
+ * @param array $input
126
+ * @return array
127
+ */
128
+ public function validateInput($input)
129
+ {
130
+ // Get new validator instance
131
+ $validator = $this->validator();
132
+
133
+ // Validate and return response
134
+ return $validator->validate($input);
135
+ }
136
+
137
+ /**
138
+ * Sanitizes the settings input
139
+ *
140
+ * @param array $input The settings input
141
+ * @return array
142
+ */
143
+ public function sanitizeInput($input = array())
144
+ {
145
+ // Return if no referer
146
+ if (empty($_POST['_wp_http_referer'])) {
147
+ return $input;
148
+ }
149
+
150
+ // Return if empty
151
+ if (empty($input)) {
152
+ return $input;
153
+ }
154
+
155
+ // Parse referer
156
+ parse_str($_POST['_wp_http_referer'], $referrer);
157
+
158
+ // Get the settings section and current tab
159
+ $settings = $this->getSections();
160
+ $tab = isset($referrer['tab']) ? $referrer['tab'] : array_shift($this->getTabs());
161
+
162
+ // Validate
163
+ $input = $this->validateInput($input);
164
+
165
+ // Tell user settings have been updated
166
+ add_settings_error('easingslider-notices', '', __('Settings updated.', 'easingslider'), 'updated');
167
+
168
+ // Merge input with current settings
169
+ return array_merge($this->option->getValue(), $input);
170
+ }
171
+
172
+ /**
173
+ * Gets the active tab
174
+ *
175
+ * @return string
176
+ */
177
+ protected function getActiveTab()
178
+ {
179
+ $tabs = $this->getTabs();
180
+
181
+ // Get from URL
182
+ if (isset($_GET['tab']) && array_key_exists($_GET['tab'], $tabs)) {
183
+ return $_GET['tab'];
184
+ }
185
+
186
+ // Fallback to first tab
187
+ return current(array_keys($tabs));
188
+ }
189
+
190
+ /**
191
+ * Gets the name for a HTML attribute
192
+ *
193
+ * @param string $attribute
194
+ * @return string
195
+ */
196
+ protected function getNameAttribute($attribute)
197
+ {
198
+ return esc_attr($this->option->getName() .'['. $attribute .']');
199
+ }
200
+
201
+ /**
202
+ * Renders the header
203
+ *
204
+ * @param array $args The setting arguments
205
+ * @return void
206
+ */
207
+ public function headerCallback($args)
208
+ {
209
+ echo '<hr />';
210
+ }
211
+
212
+ /**
213
+ * Render an information field
214
+ *
215
+ * @param array $args The setting arguments
216
+ * @return void
217
+ */
218
+ public function infoCallback($args)
219
+ {
220
+ echo $args['std'];
221
+ }
222
+
223
+ /**
224
+ * Renders a checkbox
225
+ *
226
+ * @param array $args The setting arguments
227
+ * @return void
228
+ */
229
+ public function checkboxCallback($args)
230
+ {
231
+ $checked = ($this->option[$args['id']] && true === $this->option[$args['id']]) ? true : false;
232
+
233
+ ?>
234
+ <input type="hidden" name="<?php echo $this->getNameAttribute($args['id']); ?>" value="false">
235
+ <input type="checkbox" name="<?php echo $this->getNameAttribute($args['id']); ?>" id="<?php echo esc_attr($args['id']); ?>" value="true" <?php checked(true, $checked); ?>>
236
+ <label for="<?php echo esc_attr($args['id']); ?>"><?php echo esc_html($args['desc']); ?></label>
237
+ <?php
238
+ }
239
+
240
+ /**
241
+ * Renders multiple checkboxes
242
+ *
243
+ * @param array $args The setting arguments
244
+ * @return void
245
+ */
246
+ public function multicheckCallback($args)
247
+ {
248
+ ?>
249
+ <?php if ( ! empty($args['options'])) : ?>
250
+ <?php foreach ($args['options'] as $key => $option) : ?>
251
+ <?php $checked = ($this->option[$args['id']] && $this->option[$args['id']][$key] && true === $this->option[$args['id'][$key]]) ? true : false; ?>
252
+
253
+ <input type="hidden" name="<?php echo $this->getNameAttribute($args['id']); ?>[<?php echo esc_attr($key); ?>]" value="false">
254
+ <input type="checkbox" name="<?php echo $this->getNameAttribute($args['id']); ?>[<?php echo esc_attr($key); ?>]" id="<?php echo esc_attr($args['id'] .'-'. $key); ?>" value="true" <?php checked(true, $checked); ?>>
255
+ <label for="<?php echo esc_attr($args['id'] .'-'. $key); ?>"><?php echo esc_html($option); ?></label>
256
+ <?php endforeach; ?>
257
+ <?php else : ?>
258
+ <span><?php _e('No options available.', 'easingslider'); ?></span>
259
+ <?php endif; ?>
260
+
261
+ <p class="description"><?php echo esc_html($args['desc']); ?></p>
262
+ <?php
263
+ }
264
+
265
+ /**
266
+ * Renders radio options
267
+ *
268
+ * @param array $args The setting arguments
269
+ * @return void
270
+ */
271
+ public function radioCallback($args)
272
+ {
273
+ $checked = ($this->option[$args['id']]) ? $this->option[$args['id']] : $args['std'];
274
+
275
+ ?>
276
+ <?php if ( ! empty($args['options'])) : ?>
277
+ <?php foreach ($args['options'] as $key => $option) : ?>
278
+
279
+ <input type="radio" name="<?php echo $this->getNameAttribute($args['id']); ?>" id="<?php echo esc_attr($args['id'] .'-'. $key); ?>" value="<?php echo esc_attr($key); ?>" <?php checked($key, $this->option[$args['id']]); ?>>
280
+ <label for="<?php echo esc_attr($args['id'] .'-'. $key); ?>"><?php echo esc_html($option); ?></label>
281
+ <?php endforeach; ?>
282
+ <?php else : ?>
283
+ <span><?php _e('No options available.', 'easingslider'); ?></span>
284
+ <?php endif; ?>
285
+
286
+ <p class="description"><?php echo esc_html($args['desc']); ?></p>
287
+ <?php
288
+ }
289
+
290
+ /**
291
+ * Renders a text field
292
+ *
293
+ * @param array $args The setting arguments
294
+ * @return void
295
+ */
296
+ public function textCallback($args)
297
+ {
298
+ $value = ($this->option[$args['id']]) ? $this->option[$args['id']] : $args['std'];
299
+
300
+ ?>
301
+ <input type="text" name="<?php echo $this->getNameAttribute($args['id']); ?>" id="<?php echo esc_attr($args['id']); ?>" value="<?php echo esc_attr($value); ?>">
302
+ <label for="<?php echo esc_attr($args['id']); ?>"><?php echo esc_html($args['desc']); ?></label>
303
+ <?php
304
+ }
305
+
306
+ /**
307
+ * Renders a number field
308
+ *
309
+ * @param array $args The setting arguments
310
+ * @return void
311
+ */
312
+ public function numberCallback($args)
313
+ {
314
+ $value = ($this->option[$args['id']]) ? $this->option[$args['id']] : $args['std'];
315
+
316
+ ?>
317
+ <input type="number" name="<?php echo $this->getNameAttribute($args['id']); ?>" id="<?php echo esc_attr($args['id']); ?>" min="<?php echo esc_attr($args['min']); ?>" max="<?php echo esc_attr($args['max']); ?>" step="<?php echo esc_attr($args['step']); ?>" class="<?php echo esc_attr($args['size'] .'-text'); ?>" value="<?php echo esc_attr($value); ?>">
318
+ <label for="<?php echo esc_attr($args['id']); ?>"><?php echo esc_html($args['desc']); ?></label>
319
+ <?php
320
+ }
321
+
322
+ /**
323
+ * Renders a textarea
324
+ *
325
+ * @param array $args The setting arguments
326
+ * @return void
327
+ */
328
+ public function textareaCallback($args)
329
+ {
330
+ $value = ($this->option[$args['id']]) ? $this->option[$args['id']] : $args['std'];
331
+
332
+ ?>
333
+ <textarea name="<?php echo $this->getNameAttribute($args['id']); ?>" id="<?php echo esc_attr($args['id']); ?>"><?php echo esc_html($value); ?>"></textarea>
334
+ <label for="<?php echo esc_attr($args['id']); ?>"><?php echo esc_html($args['desc']); ?></label>
335
+ <?php
336
+ }
337
+
338
+ /**
339
+ * Renders a password field
340
+ *
341
+ * @param array $args The setting arguments
342
+ * @return void
343
+ */
344
+ public function passwordCallback($args)
345
+ {
346
+ $value = ($this->option[$args['id']]) ? $this->option[$args['id']] : $args['std'];
347
+
348
+ ?>
349
+ <input type="password" name="<?php echo $this->getNameAttribute($args['id']); ?>" id="<?php echo esc_attr($args['id']); ?>" value="<?php echo esc_attr($value); ?>">
350
+ <label for="<?php echo esc_attr($args['id']); ?>"><?php echo esc_html($args['desc']); ?></label>
351
+ <?php
352
+ }
353
+
354
+ /**
355
+ * Tells the user that the specified callback is missing
356
+ *
357
+ * @param array $args The setting arguments
358
+ * @return void
359
+ */
360
+ public function missingCallback($args)
361
+ {
362
+ printf(__('The callback function used for the <strong>%s</strong> setting is missing.', 'easingslider'), $args['id']);
363
+ }
364
+
365
+ /**
366
+ * Renders a select box field
367
+ *
368
+ * @param array $args The setting arguments
369
+ * @return void
370
+ */
371
+ public function selectCallback($args)
372
+ {
373
+ $selected = ($this->option[$args['id']]) ? $this->option[$args['id']] : $args['std'];
374
+
375
+ ?>
376
+ <?php if ( ! empty($args['options'])) : ?>
377
+ <select name="<?php echo $this->getNameAttribute($args['id']); ?>">
378
+ <?php foreach ($args['options'] as $key => $option) : ?>
379
+ <option value="<?php echo esc_attr($key); ?>" <?php selected($key, $selected); ?>><?php echo esc_html($option); ?></option>
380
+ <?php endforeach; ?>
381
+ </select>
382
+ <?php else : ?>
383
+ <span><?php _e('No options available.', 'easingslider'); ?></span>
384
+ <?php endif; ?>
385
+
386
+ <label for="<?php echo esc_attr($args['id']); ?>"><?php echo esc_html($args['desc']); ?></label>
387
+ <?php
388
+ }
389
+
390
+ /**
391
+ * Renders an action field
392
+ *
393
+ * @param array $args The setting arguments
394
+ * @return void
395
+ */
396
+ public function actionCallback($args)
397
+ {
398
+ $url = wp_nonce_url("?page={$this->page}&easingslider_action={$args['action']}", $args['action']);
399
+
400
+ ?>
401
+ <a href="<?php echo esc_attr($url); ?>" class="button button-secondary delete">
402
+ <?php echo esc_html($args['label']); ?>
403
+ </a>
404
+ <p class="description"><?php echo esc_html($args['desc']); ?></p>
405
+ <?php
406
+ }
407
+
408
+ /**
409
+ * Get tabs
410
+ *
411
+ * @return array
412
+ */
413
+ abstract protected function getTabs();
414
+
415
+ /**
416
+ * Get sections
417
+ *
418
+ * @return array
419
+ */
420
+ abstract protected function getSections();
421
+
422
+ /**
423
+ * Gets a new validator instance
424
+ *
425
+ * @return array
426
+ */
427
+ abstract protected function validator();
428
+ }
src/Foundation/Admin/PluginUpdaters/EDDPluginUpdater.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\PluginUpdaters;
4
+
5
+ use EasingSlider\Foundation\Admin\PluginUpdaters\PluginUpdater;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ // Uncomment for testing
15
+ // set_site_transient('update_plugins', null);
16
+
17
+ class EDDPluginUpdater extends PluginUpdater
18
+ {
19
+ /**
20
+ * Gets the latest plugin version
21
+ *
22
+ * @return object|false
23
+ */
24
+ protected function getLatestVersion()
25
+ {
26
+ $requestParams = array(
27
+ 'edd_action'=> 'get_version',
28
+ 'license' => $this->license['key'],
29
+ 'item_name' => $this->name,
30
+ 'slug' => $this->pluginSlug,
31
+ 'author' => '',
32
+ 'url' => home_url()
33
+ );
34
+
35
+ // Get response from API
36
+ $response = wp_remote_post(
37
+ $this->getApiUrl(),
38
+ array(
39
+ 'timeout' => 15,
40
+ 'sslverify' => false,
41
+ 'body' => $requestParams
42
+ )
43
+ );
44
+
45
+ // Check for WordPress error(s)
46
+ if (is_wp_error($response)) {
47
+ return false;
48
+ }
49
+
50
+ // Get reponse body
51
+ $data = json_decode(wp_remote_retrieve_body($response));
52
+
53
+ // Bail if we got no response body
54
+ if (is_null($data)) {
55
+ return false;
56
+ }
57
+
58
+ // Unserialize sections
59
+ if (isset($data->sections)) {
60
+ $data->sections = maybe_unserialize($data->sections);
61
+ }
62
+
63
+ return $data;
64
+ }
65
+ }
src/Foundation/Admin/PluginUpdaters/PluginUpdater.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\PluginUpdaters;
4
+
5
+ use EasingSlider\Foundation\Contracts\Options\OptionArray;
6
+ use stdClass;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ // Uncomment for testing
16
+ // set_site_transient('update_plugins', null);
17
+
18
+ abstract class PluginUpdater
19
+ {
20
+ /**
21
+ * License
22
+ *
23
+ * @var \EasingSlider\Foundation\Contracts\Options\OptionArray
24
+ */
25
+ protected $license;
26
+
27
+ /**
28
+ * Name
29
+ *
30
+ * @var string
31
+ */
32
+ protected $name;
33
+
34
+ /**
35
+ * File
36
+ *
37
+ * @var string
38
+ */
39
+ protected $file;
40
+
41
+ /**
42
+ * Version
43
+ *
44
+ * @var string
45
+ */
46
+ protected $version;
47
+
48
+ /**
49
+ * Plugin Name
50
+ *
51
+ * @var string
52
+ */
53
+ protected $pluginName;
54
+
55
+ /**
56
+ * Plugin Slug
57
+ *
58
+ * @var string
59
+ */
60
+ protected $pluginSlug;
61
+
62
+ /**
63
+ * Constructor
64
+ *
65
+ * @param \EasingSlider\Foundation\Contracts\Options\OptionArray $license
66
+ * @param string $name
67
+ * @param string $file
68
+ * @param string $version
69
+ * @return void
70
+ */
71
+ public function __construct(OptionArray $license, $name, $file, $version)
72
+ {
73
+ $this->license = $license;
74
+ $this->name = $name;
75
+ $this->file = $file;
76
+ $this->version = $version;
77
+
78
+ $this->pluginName = plugin_basename($this->file);
79
+ $this->pluginSlug = basename($this->pluginName, '.php');
80
+
81
+ $this->defineHooks();
82
+ }
83
+
84
+ /**
85
+ * Define hooks
86
+ *
87
+ * @return void
88
+ */
89
+ protected function defineHooks()
90
+ {
91
+ add_filter('pre_set_site_transient_update_plugins', array($this, 'checkForUpdate'));
92
+ add_filter('plugins_api', array($this, 'getPluginDetails'), 10, 3);
93
+ }
94
+
95
+ /**
96
+ * Gets the API URL
97
+ *
98
+ * @return string
99
+ */
100
+ protected function getApiUrl()
101
+ {
102
+ return easingslider_api_url();
103
+ }
104
+
105
+ /**
106
+ * Check for Updates at the defined API endpoint and modify the update array.
107
+ *
108
+ * This function dives into the update API just when WordPress creates its update array,
109
+ * then adds a custom API call and injects the custom plugin data retrieved from the API.
110
+ * It is reassembled from parts of the native WordPress plugin update code.
111
+ * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
112
+ *
113
+ * @param array $transientData
114
+ * @return array
115
+ */
116
+ public function checkForUpdate($transientData)
117
+ {
118
+ global $pagenow;
119
+
120
+ // Create transient data object if it isn't already one
121
+ if ( ! is_object($transientData)) {
122
+ $transientData = new stdClass;
123
+ }
124
+
125
+ // If on plugins page
126
+ if ('plugins.php' == $pagenow && is_multisite()) {
127
+ return $transientData;
128
+ }
129
+
130
+ // If we have transient data for this plugin, continue checking for an update
131
+ if (empty($transientData->response) || empty($transientData->response[$this->pluginName])) {
132
+
133
+ // Get the version info
134
+ $versionInfo = $this->getLatestVersion();
135
+
136
+ // Merge version info with other plugin info
137
+ if (false !== $versionInfo && is_object($versionInfo) && isset($versionInfo->new_version)) {
138
+
139
+ // If we have a new version, add update info
140
+ if (version_compare($this->version, $versionInfo->new_version, '<')) {
141
+ $transientData->response[$this->pluginName] = $versionInfo;
142
+ }
143
+
144
+ // Set last check datetime
145
+ $transientData->last_checked = time();
146
+ $transientData->checked[$this->pluginName] = $this->version;
147
+
148
+ }
149
+
150
+ }
151
+
152
+ return $transientData;
153
+ }
154
+
155
+ /**
156
+ * Updates information on the "View version x.x details" page with custom data.
157
+ *
158
+ * @param mixed $data
159
+ * @param string $action
160
+ * @param object $args
161
+ * @return object $data
162
+ */
163
+ public function getPluginDetails($data, $action, $args)
164
+ {
165
+ // Bail if not getting plugin information
166
+ if ('plugin_information' != $action) {
167
+ return $data;
168
+ }
169
+
170
+ // Check plugin slug/basename matches
171
+ if ( ! isset($args->slug) || ($args->slug != $this->pluginSlug) ) {
172
+ return $data;
173
+ }
174
+
175
+ // Get latest version information
176
+ $versionInfo = $this->getLatestVersion();
177
+
178
+ // Check we got a response, and if so, replace data with ours
179
+ if ($versionInfo) {
180
+ $data = $versionInfo;
181
+ }
182
+
183
+ return $data;
184
+ }
185
+
186
+ /**
187
+ * Gets the latest plugin version
188
+ *
189
+ * @return object
190
+ */
191
+ abstract protected function getLatestVersion();
192
+ }
src/Foundation/Admin/Upgrades/Upgrader.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Upgrades;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Upgrades\Upgrader as UpgraderContract;
6
+ use EasingSlider\Foundation\Contracts\Options\Option;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class Upgrader implements UpgraderContract
16
+ {
17
+ /**
18
+ * Version
19
+ *
20
+ * @var \EasingSlider\Foundation\Contracts\Options\Option
21
+ */
22
+ protected $version;
23
+
24
+ /**
25
+ * The version we're upgrading from (or greater)
26
+ *
27
+ * @var string
28
+ */
29
+ protected $upgradeFrom;
30
+
31
+ /**
32
+ * The version we're upgrading too
33
+ *
34
+ * @var string
35
+ */
36
+ protected $upgradeTo;
37
+
38
+ /**
39
+ * Operator for version comparison
40
+ *
41
+ * @var string
42
+ */
43
+ protected $operator = '=';
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @param \EasingSlider\Foundation\Contracts\Options\Option $version
49
+ * @return void
50
+ */
51
+ public function __construct(Option $version)
52
+ {
53
+ $this->version = $version;
54
+ }
55
+
56
+ /**
57
+ * Checks if we meet the requirements to upgrade
58
+ *
59
+ * @return boolean
60
+ */
61
+ protected function meetsRequirements()
62
+ {
63
+ // Get the current version
64
+ $version = $this->version->getValue();
65
+
66
+ // Compare version against upgrade "to" and "from" values to ensure a strict bracket of eligible versions.
67
+ if (version_compare($version, $this->upgradeFrom, '>=')) {
68
+ if (version_compare($version, $this->upgradeTo, '<')) {
69
+ return true;
70
+ }
71
+ }
72
+
73
+ return false;
74
+ }
75
+
76
+ /**
77
+ * Updates the current plugin version.
78
+ *
79
+ * @return void
80
+ */
81
+ protected function updateVersion()
82
+ {
83
+ $this->version->setValue($this->upgradeTo);
84
+ $this->version->save();
85
+ }
86
+
87
+ /**
88
+ * Executes an upgrade, first checking the version.
89
+ *
90
+ * @return void
91
+ */
92
+ public function upgrade()
93
+ {
94
+ if ($this->meetsRequirements()) {
95
+ $this->doUpgrade();
96
+
97
+ $this->updateVersion();
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Handles the upgrade
103
+ *
104
+ * @return void
105
+ */
106
+ abstract protected function doUpgrade();
107
+ }
src/Foundation/Admin/Upgrades/Upgrades.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Upgrades;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Upgrades\Upgrades as UpgradesContract;
6
+ use EasingSlider\Foundation\Contracts\Plugin;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class Upgrades implements UpgradesContract
16
+ {
17
+ /**
18
+ * Upgrades
19
+ *
20
+ * @var array
21
+ */
22
+ protected $upgrades = array();
23
+
24
+ /**
25
+ * Plugin
26
+ *
27
+ * @var \EasingSlider\Foundation\Contracts\Plugin
28
+ */
29
+ protected $plugin;
30
+
31
+ /**
32
+ * Constructor
33
+ *
34
+ * @param \EasingSlider\Foundation\Contracts\Plugin $plugin
35
+ * @return void
36
+ */
37
+ public function __construct(Plugin $plugin)
38
+ {
39
+ $this->plugin = $plugin;
40
+
41
+ $this->defineHooks();
42
+
43
+ $this->boot();
44
+ }
45
+
46
+ /**
47
+ * Define hooks
48
+ *
49
+ * @return void
50
+ */
51
+ protected function defineHooks()
52
+ {
53
+ add_action('admin_init', array($this, 'doUpgrades'));
54
+ }
55
+
56
+ /**
57
+ * Do upgrades
58
+ *
59
+ * @return void
60
+ */
61
+ public function doUpgrades()
62
+ {
63
+ foreach ($this->upgraders as $upgrader) {
64
+ $upgrader->upgrade();
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Boot
70
+ *
71
+ * @return void
72
+ */
73
+ abstract protected function boot();
74
+ }
src/Foundation/Admin/Validators/Validator.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Admin\Validators;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Validators\Validator as ValidatorContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Validator implements ValidatorContract
15
+ {
16
+ /**
17
+ * Rules
18
+ *
19
+ * @var array
20
+ */
21
+ protected $rules;
22
+
23
+ /**
24
+ * Constructor
25
+ *
26
+ * @return void
27
+ */
28
+ public function __construct()
29
+ {
30
+ $this->rules = $this->getRules();
31
+ }
32
+
33
+ /**
34
+ * Gets the validation rule for the provided key
35
+ *
36
+ * @param string $key
37
+ * @return string|false
38
+ */
39
+ protected function getRule($key)
40
+ {
41
+ if (isset($this->rules[$key])) {
42
+ return $this->rules[$key];
43
+ }
44
+
45
+ return false;
46
+ }
47
+
48
+ /**
49
+ * Validates a specific value
50
+ *
51
+ * @param string $rule
52
+ * @param mixed $value
53
+ * @return mixed
54
+ */
55
+ public function validateValue($rule, $value)
56
+ {
57
+ switch ($rule) {
58
+ case 'integer' :
59
+ return $this->validateInteger($value);
60
+ break;
61
+
62
+ case 'boolean' :
63
+ return $this->validateBoolean($value);
64
+ break;
65
+
66
+ case 'string' :
67
+ return $this->validateString($value);
68
+ break;
69
+
70
+ case 'array' :
71
+ return array_map(array($this, 'validateString'), $value);
72
+ break;
73
+
74
+ case 'decode_json_array' :
75
+ return $this->decodeJsonArray($value);
76
+ break;
77
+ }
78
+
79
+ return $value;
80
+ }
81
+
82
+ /**
83
+ * Validate integer
84
+ *
85
+ * @param string $value
86
+ * @return int
87
+ */
88
+ public function validateInteger($value)
89
+ {
90
+ return intval($value);
91
+ }
92
+
93
+ /**
94
+ * Validate boolean
95
+ *
96
+ * @param string $value
97
+ * @return boolean
98
+ */
99
+ protected function validateBoolean($value)
100
+ {
101
+ return filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
102
+ }
103
+
104
+ /**
105
+ * Validate string
106
+ *
107
+ * @param string $value
108
+ * @return string
109
+ */
110
+ protected function validateString($value)
111
+ {
112
+ return sanitize_text_field($value);
113
+ }
114
+
115
+ /**
116
+ * Decodes a JSON array
117
+ *
118
+ * @param array $value
119
+ * @return array
120
+ */
121
+ protected function decodeJsonArray($value)
122
+ {
123
+ if ( ! is_array($value)) {
124
+ return array();
125
+ }
126
+
127
+ return array_map('json_decode', array_map('stripslashes', $value));
128
+ }
129
+
130
+ /**
131
+ * Validates the provided data
132
+ *
133
+ * @param array $data
134
+ * @return array
135
+ */
136
+ public function validate($data)
137
+ {
138
+ // Validate each data item
139
+ foreach ($data as $key => $value) {
140
+
141
+ // Get the validation rule
142
+ $rule = $this->getRule($key);
143
+
144
+ // Validate the value, if we have a rule
145
+ if ($rule) {
146
+ $data[$key] = $this->validateValue($rule, $value);
147
+ }
148
+
149
+ }
150
+
151
+ return $data;
152
+ }
153
+
154
+ /**
155
+ * Gets the validation rules
156
+ *
157
+ * @return array
158
+ */
159
+ abstract protected function getRules();
160
+ }
src/Foundation/Assets/Assets.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Assets;
4
+
5
+ use EasingSlider\Foundation\Contracts\Assets\Assets as AssetsContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Assets implements AssetsContract
15
+ {
16
+ /**
17
+ * Gets the suffix
18
+ *
19
+ * @return string
20
+ */
21
+ protected function getSuffix()
22
+ {
23
+ // Get suffix based on script debugging flag
24
+ return (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
25
+ }
26
+
27
+ /**
28
+ * Enqueues the assets
29
+ *
30
+ * @return void
31
+ */
32
+ abstract public function enqueue();
33
+ }
src/Foundation/Capabilities/Capabilities.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Capabilities;
4
+
5
+ use EasingSlider\Foundation\Contracts\Capabilities\Capabilities as CapabilitiesContract;
6
+ use WP_Roles;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class Capabilities implements CapabilitiesContract
16
+ {
17
+ /**
18
+ * Capabilities
19
+ *
20
+ * @var array
21
+ */
22
+ protected $capabilities;
23
+
24
+ /**
25
+ * Constructor
26
+ *
27
+ * @return void
28
+ */
29
+ public function __construct()
30
+ {
31
+ $this->capabilities = $this->getCapabilities();
32
+ }
33
+
34
+ /**
35
+ * Gets the user roles
36
+ *
37
+ * @return \WP_Roles
38
+ */
39
+ protected function getUserRoles()
40
+ {
41
+ global $wp_roles;
42
+
43
+ if ( ! isset($wp_roles)) {
44
+ $wp_roles = new WP_Roles();
45
+ }
46
+
47
+ return $wp_roles;
48
+ }
49
+
50
+ /**
51
+ * Adds the capabilities to all user roles
52
+ *
53
+ * @return void
54
+ */
55
+ public function addToRoles()
56
+ {
57
+ $userRoles = $this->getUserRoles();
58
+
59
+ foreach ($userRoles->roles as $role => $object) {
60
+ foreach ($this->capabilities as $capability) {
61
+ $userRoles->add_cap($role, $capability);
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Removes the capabilities from all user roles
68
+ *
69
+ * @return void
70
+ */
71
+ public function removeFromRoles()
72
+ {
73
+ $userRoles = $this->getUserRoles();
74
+
75
+ foreach ($userRoles->roles as $role => $object) {
76
+ foreach ($this->capabilities as $capability) {
77
+ $userRoles->remove_cap($role, $capability);
78
+ }
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Gets the capabilities
84
+ *
85
+ * @return array
86
+ */
87
+ abstract protected function getCapabilities();
88
+ }
src/Foundation/Contracts/Activation/Activator.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Activation;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Activator
13
+ {
14
+ /**
15
+ * Executes activation
16
+ *
17
+ * @return void
18
+ */
19
+ public function activate();
20
+ }
src/Foundation/Contracts/Admin/Actions/Actions.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Actions;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Actions
13
+ {
14
+ //
15
+ }
src/Foundation/Contracts/Admin/Actions/Processor.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Actions;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Processor
13
+ {
14
+ /**
15
+ * Processes an action
16
+ *
17
+ * @return void
18
+ */
19
+ public function process();
20
+ }
src/Foundation/Contracts/Admin/Actions/ResourceActions.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Actions;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface ResourceActions
13
+ {
14
+ /**
15
+ * Action for creating a resource
16
+ *
17
+ * @param array $data
18
+ * @return void
19
+ */
20
+ public function create($data = array());
21
+
22
+ /**
23
+ * Action for updating a resource
24
+ *
25
+ * @param array $data
26
+ * @return void
27
+ */
28
+ public function update($data = array());
29
+
30
+ /**
31
+ * Action for duplicating a resource
32
+ *
33
+ * @param array $data
34
+ * @return void
35
+ */
36
+ public function duplicate($data = array());
37
+
38
+ /**
39
+ * Action for trash a resource
40
+ *
41
+ * @param array $data
42
+ * @return void
43
+ */
44
+ public function trash($data = array());
45
+
46
+ /**
47
+ * Action for untrashing a resource
48
+ *
49
+ * @param array $data
50
+ * @return void
51
+ */
52
+ public function untrash($data = array());
53
+
54
+ /**
55
+ * Action for deleting a resource
56
+ *
57
+ * @param array $data
58
+ * @return void
59
+ */
60
+ public function delete($data = array());
61
+ }
src/Foundation/Contracts/Admin/Admin.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Admin
13
+ {
14
+ //
15
+ }
src/Foundation/Contracts/Admin/Ajax/Router.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Ajax;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Router
13
+ {
14
+ /**
15
+ * Sets an ajax route action
16
+ *
17
+ * @param string $action
18
+ * @param string|array $callback
19
+ * @param boolean $requiresAuth
20
+ * @return void
21
+ */
22
+ public function setAction($action, $callback, $requiresAuth = true);
23
+ }
src/Foundation/Contracts/Admin/Assets/Assets.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Assets;
4
+
5
+ use EasingSlider\Foundation\Contracts\Assets\Assets as BaseAssets;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface Assets extends BaseAssets
15
+ {
16
+ //
17
+ }
src/Foundation/Contracts/Admin/LicenseHandlers/LicenseHandler.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\LicenseHandlers;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface LicenseHandler
13
+ {
14
+ /**
15
+ * Gets the license key
16
+ *
17
+ * @return string
18
+ */
19
+ public function getKey();
20
+
21
+ /**
22
+ * Sets the license key
23
+ *
24
+ * @param string $key
25
+ * @return void
26
+ */
27
+ public function setKey($key);
28
+
29
+ /**
30
+ * Sets the license status
31
+ *
32
+ * @param string $status
33
+ * @return void
34
+ */
35
+ public function setStatus($status);
36
+
37
+ /**
38
+ * Checks if a license is valid
39
+ *
40
+ * @return boolean
41
+ */
42
+ public function isValid();
43
+
44
+ /**
45
+ * Activates the license key
46
+ *
47
+ * @return boolean
48
+ */
49
+ public function activate();
50
+
51
+ /**
52
+ * Deactivates the license key
53
+ *
54
+ * @return boolean
55
+ */
56
+ public function deactivate();
57
+ }
src/Foundation/Contracts/Admin/ListTables/ListTable.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\ListTables;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface ListTable
13
+ {
14
+ //
15
+ }
src/Foundation/Contracts/Admin/Menus/Menu.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Menus;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Menu
13
+ {
14
+ //
15
+ }
src/Foundation/Contracts/Admin/Notices/Notice.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Notices;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Notice
13
+ {
14
+ /**
15
+ * Displays the notice
16
+ *
17
+ * @return void
18
+ */
19
+ public function display();
20
+ }
src/Foundation/Contracts/Admin/Notices/NoticeHandler.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Notices;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Notices\Notice;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface NoticeHandler
15
+ {
16
+ /**
17
+ * Shows a success notice
18
+ *
19
+ * @param string $handle
20
+ * @param string $message
21
+ * @return void
22
+ */
23
+ public function success($handle, $message);
24
+
25
+ /**
26
+ * Shows an error notice
27
+ *
28
+ * @param string $handle
29
+ * @param string $message
30
+ * @return void
31
+ */
32
+ public function error($handle, $message);
33
+
34
+ /**
35
+ * Shows an info notice
36
+ *
37
+ * @param string $handle
38
+ * @param string $message
39
+ * @return void
40
+ */
41
+ public function info($handle, $message);
42
+ }
src/Foundation/Contracts/Admin/Panels/Panel.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Panels;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Panel
13
+ {
14
+ /**
15
+ * Displays the panel
16
+ *
17
+ * @return void
18
+ */
19
+ public function display();
20
+ }
src/Foundation/Contracts/Admin/Panels/Panels.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Panels;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Panels
13
+ {
14
+ //
15
+ }
src/Foundation/Contracts/Admin/PluginUpdaters/.gitkeep ADDED
File without changes
src/Foundation/Contracts/Admin/PluginUpdaters/PluginUpdater.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\PluginUpdaters;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface PluginUpdater
13
+ {
14
+ //
15
+ }
src/Foundation/Contracts/Admin/Upgrades/Upgrader.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Upgrades;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Upgrader
13
+ {
14
+ /**
15
+ * Executes an upgrade
16
+ *
17
+ * @return void
18
+ */
19
+ public function upgrade();
20
+ }
src/Foundation/Contracts/Admin/Upgrades/Upgrades.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Upgrades;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Upgrades
13
+ {
14
+ //
15
+ }
src/Foundation/Contracts/Admin/Validators/Validator.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Admin\Validators;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Validator
13
+ {
14
+ /**
15
+ * Validates the provided data
16
+ *
17
+ * @param array $data
18
+ * @return array
19
+ */
20
+ public function validate($data);
21
+ }
src/Foundation/Contracts/Assets/Assets.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Assets;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Assets
13
+ {
14
+ /**
15
+ * Enqueues the assets
16
+ *
17
+ * @return void
18
+ */
19
+ public function enqueue();
20
+ }
src/Foundation/Contracts/Capabilities/Capabilities.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Capabilities;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Capabilities
13
+ {
14
+ /**
15
+ * Adds the capabilities to all user roles
16
+ *
17
+ * @return void
18
+ */
19
+ public function addToRoles();
20
+
21
+ /**
22
+ * Removes the capabilities from all user roles
23
+ *
24
+ * @return void
25
+ */
26
+ public function removeFromRoles();
27
+ }
src/Foundation/Contracts/Models/Model.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Models;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Model
13
+ {
14
+ /**
15
+ * Fills attributes
16
+ *
17
+ * @param array $data
18
+ * @return void
19
+ */
20
+ public function fill($data = array());
21
+
22
+ /**
23
+ * Set an attribute value
24
+ *
25
+ * @param string $key
26
+ * @param mixed $value
27
+ * @return void
28
+ */
29
+ public function set($key, $value);
30
+
31
+ /**
32
+ * Get an attribute value
33
+ *
34
+ * @param string $key
35
+ * @return array
36
+ */
37
+ public function get($key);
38
+
39
+ /**
40
+ * Gets the model attributes
41
+ *
42
+ * @return array
43
+ */
44
+ public function getAttributes();
45
+ }
src/Foundation/Contracts/Options/Option.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Options;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Option
13
+ {
14
+ /**
15
+ * Gets the option name
16
+ *
17
+ * @return string
18
+ */
19
+ public function getName();
20
+
21
+ /**
22
+ * Gets the option value
23
+ *
24
+ * @return mixed
25
+ */
26
+ public function getValue();
27
+
28
+ /**
29
+ * Sets the option value
30
+ *
31
+ * @param mixed $value
32
+ * @return void
33
+ */
34
+ public function setValue($value);
35
+
36
+ /**
37
+ * Saves the option
38
+ *
39
+ * @return viod
40
+ */
41
+ public function save();
42
+
43
+ /**
44
+ * Deletes the option
45
+ *
46
+ * @return void
47
+ */
48
+ public function delete();
49
+ }
src/Foundation/Contracts/Options/OptionArray.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Options;
4
+
5
+ use ArrayAccess;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface OptionArray extends ArrayAccess
15
+ {
16
+ /**
17
+ * Saves the option
18
+ *
19
+ * @return viod
20
+ */
21
+ public function save();
22
+
23
+ /**
24
+ * Deletes the option
25
+ *
26
+ * @return void
27
+ */
28
+ public function delete();
29
+ }
src/Foundation/Contracts/Plugin.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Plugin
13
+ {
14
+ //
15
+ }
src/Foundation/Contracts/Repositories/Repository.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Repositories;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Repository
13
+ {
14
+ /**
15
+ * Get all models
16
+ *
17
+ * @return array
18
+ */
19
+ public function all();
20
+
21
+ /**
22
+ * Finds a model
23
+ *
24
+ * @param int $id
25
+ * @return \EasingSlider\Foundation\Models\ModelContract
26
+ */
27
+ public function find($id);
28
+
29
+ /**
30
+ * Stores a new model in the database
31
+ *
32
+ * @param array $data
33
+ * @return int|false
34
+ */
35
+ public function create($data = array());
36
+
37
+ /**
38
+ * Updates a model in the databse
39
+ *
40
+ * @param int $id
41
+ * @param array $data
42
+ * @return int|false
43
+ */
44
+ public function update($id, $data = array());
45
+
46
+ /**
47
+ * Duplicates a model
48
+ *
49
+ * @param int $id
50
+ * @return int|false
51
+ */
52
+ public function duplicate($id);
53
+
54
+ /**
55
+ * Trashes a model
56
+ *
57
+ * @param int $id
58
+ * @return int|false
59
+ */
60
+ public function trash($id);
61
+
62
+ /**
63
+ * Untrashes a model
64
+ *
65
+ * @param int $id
66
+ * @return object|false
67
+ */
68
+ public function untrash($id);
69
+
70
+ /**
71
+ * Deletes a model permanently
72
+ *
73
+ * @param int $id
74
+ * @return int|false
75
+ */
76
+ public function delete($id);
77
+
78
+ /**
79
+ * Gets the total model count
80
+ *
81
+ * @param string $status
82
+ * @return int
83
+ */
84
+ public function total($status = 'publish');
85
+
86
+ /**
87
+ * Makes a new model instance
88
+ *
89
+ * @param array $data
90
+ * @return \EasingSlider\Foundation\Models\ModelContract
91
+ */
92
+ public function make($data = array());
93
+ }
src/Foundation/Contracts/Shortcodes/Shortcode.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Shortcodes;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Shortcode
13
+ {
14
+ /**
15
+ * Returns the shortcode tag
16
+ *
17
+ * @return string
18
+ */
19
+ public function tag();
20
+
21
+ /**
22
+ * Renders the shortcode
23
+ *
24
+ * @param array $atts The shortcode attributes
25
+ * @return string
26
+ */
27
+ public function render($atts = array());
28
+ }
src/Foundation/Contracts/TemplateLoaders/TemplateLoader.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\TemplateLoaders;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface TemplateLoader
13
+ {
14
+ /**
15
+ * Retrieves a template part. Taken from bbPress and modified to suit.
16
+ *
17
+ * @param array $data The data to be inserted
18
+ * @param string $slug The template slug
19
+ * @param string $name The template name
20
+ * @param boolean $load Whether to load the template or return it
21
+ * @return string
22
+ */
23
+ public function getTemplatePart($data, $slug, $name = null, $load = true);
24
+ }
src/Foundation/Contracts/Uninstallation/Uninstaller.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Uninstallation;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Uninstaller
13
+ {
14
+ /**
15
+ * Executes uninstallation
16
+ *
17
+ * @return void
18
+ */
19
+ public function uninstall();
20
+ }
src/Foundation/Contracts/Widgets/Widget.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Contracts\Widgets;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ interface Widget
13
+ {
14
+ //
15
+ }
src/Foundation/Models/Model.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Models;
4
+
5
+ use EasingSlider\Foundation\Contracts\Models\Model as ModelContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Model implements ModelContract
15
+ {
16
+ /**
17
+ * Attributes
18
+ *
19
+ * @var array
20
+ */
21
+ protected $attributes;
22
+
23
+ /**
24
+ * Constructor
25
+ *
26
+ * @return void
27
+ */
28
+ public function __construct()
29
+ {
30
+ $this->attributes = $this->getDefaults();
31
+ }
32
+
33
+ /**
34
+ * __get function.
35
+ *
36
+ * @param string $key
37
+ * @return mixed
38
+ */
39
+ public function __get($key)
40
+ {
41
+ return $this->get($key);
42
+ }
43
+
44
+ /**
45
+ * __set function.
46
+ *
47
+ * @param string $key
48
+ * @param mixed $value
49
+ */
50
+ public function __set($key, $value)
51
+ {
52
+ $this->set($key, $value);
53
+ }
54
+
55
+ /**
56
+ * __isset function.
57
+ *
58
+ * @param string $key
59
+ * @return bool
60
+ */
61
+ public function __isset($key)
62
+ {
63
+ return isset($this->attributes[$key]);
64
+ }
65
+
66
+ /**
67
+ * Fills attributes
68
+ *
69
+ * @param array $data
70
+ * @return void
71
+ */
72
+ public function fill($data = array())
73
+ {
74
+ foreach ($data as $key => $value) {
75
+ $this->set($key, $value);
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Set an attribute value
81
+ *
82
+ * @param string $key
83
+ * @param mixed $value
84
+ * @return void
85
+ */
86
+ public function set($key, $value)
87
+ {
88
+ $this->attributes[$key] = $value;
89
+ }
90
+
91
+ /**
92
+ * Get an attribute value
93
+ *
94
+ * @param string $key
95
+ * @return array
96
+ */
97
+ public function get($key)
98
+ {
99
+ return $this->attributes[$key];
100
+ }
101
+
102
+ /**
103
+ * Gets the model attributes
104
+ *
105
+ * @return array
106
+ */
107
+ public function getAttributes()
108
+ {
109
+ return $this->attributes;
110
+ }
111
+
112
+ /**
113
+ * Gets the model defaults
114
+ *
115
+ * @return array
116
+ */
117
+ abstract public function getDefaults();
118
+ }
src/Foundation/Options/Option.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Options;
4
+
5
+ use EasingSlider\Foundation\Contracts\Options\Option as OptionContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Option implements OptionContract
15
+ {
16
+ /**
17
+ * Name
18
+ *
19
+ * @var string
20
+ */
21
+ protected $name;
22
+
23
+ /**
24
+ * Value
25
+ *
26
+ * @var mixed
27
+ */
28
+ public $value;
29
+
30
+ /**
31
+ * Constructor
32
+ *
33
+ * @return void
34
+ */
35
+ public function __construct()
36
+ {
37
+ $this->value = $this->getValue();
38
+
39
+ add_option($this->name, $this->getDefaults());
40
+ }
41
+
42
+ /**
43
+ * Gets the option name
44
+ *
45
+ * @return string
46
+ */
47
+ public function getName()
48
+ {
49
+ return $this->name;
50
+ }
51
+
52
+ /**
53
+ * Gets the option value
54
+ *
55
+ * @return mixed
56
+ */
57
+ public function getValue()
58
+ {
59
+ return get_option($this->name, $this->getDefaults());
60
+ }
61
+
62
+ /**
63
+ * Sets the option value
64
+ *
65
+ * @param mixed $value
66
+ * @return void
67
+ */
68
+ public function setValue($value)
69
+ {
70
+ $this->value = $value;
71
+ }
72
+
73
+ /**
74
+ * Saves the option
75
+ *
76
+ * @return viod
77
+ */
78
+ public function save()
79
+ {
80
+ update_option($this->name, $this->value);
81
+ }
82
+
83
+ /**
84
+ * Deletes the option
85
+ *
86
+ * @return void
87
+ */
88
+ public function delete()
89
+ {
90
+ delete_option($this->name);
91
+ }
92
+
93
+ /**
94
+ * Gets the default settings
95
+ *
96
+ * @return mixed
97
+ */
98
+ abstract public function getDefaults();
99
+ }
src/Foundation/Options/OptionArray.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Options;
4
+
5
+ use EasingSlider\Foundation\Contracts\Options\OptionArray as OptionArrayContract;
6
+ use EasingSlider\Foundation\Options\Option;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class OptionArray extends Option implements OptionArrayContract
16
+ {
17
+ /**
18
+ * Checks if an offset exists
19
+ *
20
+ * @param mixed $offset
21
+ * @return boolean
22
+ */
23
+ public function offsetExists($offset)
24
+ {
25
+ return isset($this->value[$offset]);
26
+ }
27
+
28
+ /**
29
+ * Gets an offset
30
+ *
31
+ * @param mixed $offset
32
+ * @return mixed
33
+ */
34
+ public function offsetGet($offset)
35
+ {
36
+ return $this->value[$offset];
37
+ }
38
+
39
+ /**
40
+ * Sets a value
41
+ *
42
+ * @param mixed $offset
43
+ * @param mixed $value
44
+ * @return void
45
+ */
46
+ public function offsetSet($offset, $value)
47
+ {
48
+ $this->value[$offset] = $value;
49
+ }
50
+
51
+ /**
52
+ * Unsets a value
53
+ *
54
+ * @param int $offset
55
+ * @return void
56
+ */
57
+ public function offsetUnset($offset)
58
+ {
59
+ unset($this->value[$offset]);
60
+ }
61
+ }
src/Foundation/Plugin.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation;
4
+
5
+ use Auryn\Injector as Container;
6
+ use EasingSlider\Foundation\Contracts\Plugin as PluginContract;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class Plugin extends Container implements PluginContract
16
+ {
17
+ /**
18
+ * The one true plugin instance
19
+ *
20
+ * @var \EasingSlider\Foundation\Plugin
21
+ */
22
+ private static $instance;
23
+
24
+ /**
25
+ * Aliases
26
+ *
27
+ * @var array
28
+ */
29
+ protected $aliases = array();
30
+
31
+ /**
32
+ * Singletons
33
+ *
34
+ * @var array
35
+ */
36
+ protected $singletons = array();
37
+
38
+ /**
39
+ * Main plugin instance
40
+ *
41
+ * Insures that only one instance of our plugin exists in memory at any one
42
+ * time. Also prevents needing to define globals all over the place.
43
+ *
44
+ * @return \EasingSlider\Foundation\Plugin
45
+ */
46
+ public final static function instance()
47
+ {
48
+ // Create instance if not already created
49
+ if ( ! isset(self::$instance) && ! (self::$instance instanceof static)) {
50
+ self::$instance = new static();
51
+ self::$instance->bindAliases();
52
+ self::$instance->bindSingletons();
53
+ self::$instance->boot();
54
+ }
55
+
56
+ return self::$instance;
57
+ }
58
+
59
+ /**
60
+ * __call function.
61
+ *
62
+ * @param string $name
63
+ * @param array $arguments
64
+ * @return mixed
65
+ */
66
+ public function __call($name, $arguments)
67
+ {
68
+ if (isset($this->$name)) {
69
+ return $this->$name;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Bind aliases
75
+ *
76
+ * @return void
77
+ */
78
+ protected function bindAliases()
79
+ {
80
+ foreach ($this->aliases as $contract => $class) {
81
+ $this->alias($contract, $class);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Bind singletons
87
+ *
88
+ * @return void
89
+ */
90
+ protected function bindSingletons()
91
+ {
92
+ foreach ($this->singletons as $singleton) {
93
+ $this->share($singleton);
94
+ }
95
+
96
+ $this->share($this);
97
+ }
98
+
99
+ /**
100
+ * Boots the plugin
101
+ *
102
+ * @return void
103
+ */
104
+ abstract protected function boot();
105
+ }
src/Foundation/Repositories/PostType.php ADDED
@@ -0,0 +1,462 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Repositories;
4
+
5
+ use EasingSlider\Foundation\Contracts\Repositories\Repository as RepositoryContract;
6
+ use stdClass;
7
+ use WP_Post;
8
+ use WP_Query;
9
+
10
+ /**
11
+ * Exit if accessed directly
12
+ */
13
+ if ( ! defined('ABSPATH')) {
14
+ exit;
15
+ }
16
+
17
+ abstract class PostType implements RepositoryContract
18
+ {
19
+ /**
20
+ * Post Type
21
+ *
22
+ * @var string
23
+ */
24
+ protected $postType;
25
+
26
+ /**
27
+ * Meta Key
28
+ *
29
+ * @var string
30
+ */
31
+ protected $metaKey;
32
+
33
+ /**
34
+ * Constructor
35
+ *
36
+ * @return void
37
+ */
38
+ public function __construct()
39
+ {
40
+ $this->defineHooks();
41
+ }
42
+
43
+ /**
44
+ * Define hooks
45
+ *
46
+ * @return void
47
+ */
48
+ protected function defineHooks()
49
+ {
50
+ add_action('init', array($this, 'registerPostType'));
51
+ }
52
+
53
+ /**
54
+ * Get all models
55
+ *
56
+ * @param string $status
57
+ * @return array
58
+ */
59
+ public function all($status = 'all')
60
+ {
61
+ $models = array();
62
+
63
+ // Get our posts
64
+ $posts = $this->queryPosts(array('post_status' => $status))->get_posts();
65
+
66
+ // Create a new model instance for each post and add to results
67
+ foreach ($posts as $post) {
68
+ $models[] = $this->make($post);
69
+ }
70
+
71
+ return $models;
72
+ }
73
+
74
+ /**
75
+ * Finds a model
76
+ *
77
+ * @param int $id
78
+ * @return \EasingSlider\Foundation\Models\ModelContract|false
79
+ */
80
+ public function find($id)
81
+ {
82
+ $post = get_post($id, ARRAY_A);
83
+ $postMeta = $this->getPostMeta($id);
84
+
85
+ // Bail if no post or metadata were found
86
+ if ( ! $post || ! $postMeta || 'trash' == $post['post_status']) {
87
+ return false;
88
+ }
89
+
90
+ // Bail if not our post type
91
+ if ($post['post_type'] != $this->postType) {
92
+ return false;
93
+ }
94
+
95
+ // Initiate a model instance with data
96
+ $model = $this->make(array_merge((array) $post, (array) $postMeta));
97
+
98
+ return $model;
99
+ }
100
+
101
+ /**
102
+ * Stores a new model in the database
103
+ *
104
+ * @param array $data
105
+ * @return \EasingSlider\Foundation\Models\ModelContract|false
106
+ */
107
+ public function create($data = array())
108
+ {
109
+ // Create the post
110
+ $id = wp_insert_post($this->purgeMetaData($data));
111
+
112
+ // Bail on failure
113
+ if ( ! $id) {
114
+ return false;
115
+ }
116
+
117
+ // Add the metadata
118
+ $this->addPostMeta($id, $this->purgePostData($data));
119
+
120
+ return $this->find($id);
121
+ }
122
+
123
+ /**
124
+ * Updates a model in the databse
125
+ *
126
+ * @param int $id
127
+ * @param array $data
128
+ * @return \EasingSlider\Foundation\Models\ModelContract|false
129
+ */
130
+ public function update($id, $data = array())
131
+ {
132
+ // Update the post
133
+ $id = wp_update_post(array_merge(array('ID' => $id), $this->purgeMetaData($data)));
134
+
135
+ // Bail on failure
136
+ if ( ! $id) {
137
+ return false;
138
+ }
139
+
140
+ // Update the metadata
141
+ $this->updatePostMeta($id, $this->purgePostData($data));
142
+
143
+ return $this->find($id);
144
+ }
145
+
146
+ /**
147
+ * Duplicates a model
148
+ *
149
+ * @param int $id
150
+ * @return \EasingSlider\Foundation\Models\ModelContract|false
151
+ */
152
+ public function duplicate($id)
153
+ {
154
+ // Get the model
155
+ $model = $this->find($id);
156
+
157
+ // Bail if it doesn't exist
158
+ if ( ! $model) {
159
+ return false;
160
+ }
161
+
162
+ // Get the attributes
163
+ $attributes = $model->getAttributes();
164
+
165
+ // Remove ID
166
+ unset($attributes['ID']);
167
+
168
+ // Create & return the new model
169
+ return $this->create($attributes);
170
+ }
171
+
172
+ /**
173
+ * Trashes a model
174
+ *
175
+ * @param int $id
176
+ * @return \EasingSlider\Foundation\Models\ModelContract|false
177
+ */
178
+ public function trash($id)
179
+ {
180
+ // Trash the post
181
+ $id = wp_trash_post($id);
182
+
183
+ // Bail on failure
184
+ if ( ! $id) {
185
+ return false;
186
+ }
187
+
188
+ return $this->find($id);
189
+ }
190
+
191
+ /**
192
+ * Untrashes a model
193
+ *
194
+ * @param int $id
195
+ * @return \EasingSlider\Foundation\Models\ModelContract|false
196
+ */
197
+ public function untrash($id)
198
+ {
199
+ // Untrash the post
200
+ $id = wp_untrash_post($id);
201
+
202
+ // Bail on failure
203
+ if ( ! $id) {
204
+ return false;
205
+ }
206
+
207
+ return $this->find($id);
208
+ }
209
+
210
+ /**
211
+ * Deletes a model permanently
212
+ *
213
+ * @param int $id
214
+ * @return boolean
215
+ */
216
+ public function delete($id)
217
+ {
218
+ // Delete the post
219
+ $post = wp_delete_post($id);
220
+
221
+ // Bail if failed
222
+ if ( ! $post) {
223
+ return false;
224
+ }
225
+
226
+ // Delete the metadata
227
+ $this->deletePostMeta($id);
228
+
229
+ return true;
230
+ }
231
+
232
+ /**
233
+ * Gets the total model count
234
+ *
235
+ * @param string $status
236
+ * @return int
237
+ */
238
+ public function total($status = 'publish')
239
+ {
240
+ $postCount = wp_count_posts($this->postType);
241
+
242
+ if ( ! empty($postCount->$status)) {
243
+ return $postCount->$status;
244
+ } else {
245
+ return 0;
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Makes a new model instance
251
+ *
252
+ * @param array $data
253
+ * @return \EasingSlider\Foundation\Models\ModelContract
254
+ */
255
+ public function make($data = array())
256
+ {
257
+ $model = $this->newModel();
258
+ $model->fill(array_merge($this->defaultPostData(), (array) $data));
259
+
260
+ return $model;
261
+ }
262
+
263
+ /**
264
+ * Queries the post type
265
+ *
266
+ * @param array $arguments
267
+ * @return \WP_Query
268
+ */
269
+ public function queryPosts($arguments = array())
270
+ {
271
+ return new WP_Query(array_merge($this->defaultQueryArguments(), (array) $arguments));
272
+ }
273
+
274
+ /**
275
+ * Registers our post type
276
+ *
277
+ * @return void
278
+ */
279
+ public function registerPostType()
280
+ {
281
+ register_post_type($this->postType, array(
282
+ 'query_var' => false,
283
+ 'rewrite' => false,
284
+ 'public' => true,
285
+ 'exclude_from_search' => true,
286
+ 'publicly_queryable' => false,
287
+ 'show_in_nav_menus' => false,
288
+ 'show_ui' => false,
289
+ 'labels' => array('name' => $this->getPostTypeLabel())
290
+ ));
291
+ }
292
+
293
+ /**
294
+ * Gets the default query arguments
295
+ *
296
+ * @return array
297
+ */
298
+ protected function defaultQueryArguments()
299
+ {
300
+ return array(
301
+ 'post_status' => 'publish',
302
+ 'post_type' => $this->postType,
303
+ 'orderby' => 'ID',
304
+ 'order' => 'asc',
305
+ 'posts_per_page' => -1
306
+ );
307
+ }
308
+
309
+ /**
310
+ * Gets the default post data
311
+ *
312
+ * @return array
313
+ */
314
+ protected function defaultPostData()
315
+ {
316
+ return array(
317
+ 'post_title' => '(no title)',
318
+ 'post_status' => 'publish',
319
+ 'post_type' => $this->postType,
320
+ );
321
+ }
322
+
323
+ /**
324
+ * Gets the whitelist of post data attributes
325
+ *
326
+ * @return array
327
+ */
328
+ protected function getPostDataWhitelist()
329
+ {
330
+ $whitelist = array();
331
+
332
+ // Get a new post instance
333
+ $post = new WP_Post(new stdClass);
334
+
335
+ // Add columns as whitelisted attributes
336
+ foreach ($post->to_array() as $key => $value) {
337
+ $whitelist[] = $key;
338
+ }
339
+
340
+ return $whitelist;
341
+ }
342
+
343
+ /**
344
+ * Gets the whitelist of metadata attributes
345
+ *
346
+ * @return array
347
+ */
348
+ protected function getMetaDataWhitelist()
349
+ {
350
+ $whitelist = array();
351
+
352
+ // Get a new model instance
353
+ $modelAttributes = $this->newModel()->getAttributes();
354
+
355
+ // Add attributes to whitelist
356
+ foreach ($modelAttributes as $key => $value) {
357
+ $whitelist[] = $key;
358
+ }
359
+
360
+ return $whitelist;
361
+ }
362
+
363
+ /**
364
+ * Purges any post related data from the input data provided
365
+ *
366
+ * @param array $data
367
+ * @return array
368
+ */
369
+ protected function purgePostData($data)
370
+ {
371
+ return $this->purgeRedundantData($data, $this->getMetaDataWhitelist());
372
+ }
373
+
374
+ /**
375
+ * Purges any metadata from the input data provided
376
+ *
377
+ * @param array $data
378
+ * @return array
379
+ */
380
+ protected function purgeMetaData($data)
381
+ {
382
+ return $this->purgeRedundantData($data, $this->getPostDataWhitelist());
383
+ }
384
+
385
+ /**
386
+ * Purges redundant data from the provided input data
387
+ *
388
+ * @param array $data
389
+ * @param array $whitelist
390
+ * @return array
391
+ */
392
+ protected function purgeRedundantData($data, $whitelist)
393
+ {
394
+ foreach ($data as $key => $value) {
395
+ if ( ! in_array($key, $whitelist)) {
396
+ unset($data[$key]);
397
+ }
398
+ }
399
+
400
+ return $data;
401
+ }
402
+
403
+ /**
404
+ * Gets the metadata for a post
405
+ *
406
+ * @param int $id
407
+ * @return array
408
+ */
409
+ protected function getPostMeta($id)
410
+ {
411
+ return get_post_meta($id, $this->metaKey, true);
412
+ }
413
+
414
+ /**
415
+ * Adds the metadata to a post
416
+ *
417
+ * @param int $id
418
+ * @param array $data
419
+ * @return int
420
+ */
421
+ protected function addPostMeta($id, $data = array())
422
+ {
423
+ return add_post_meta($id, $this->metaKey, $data);
424
+ }
425
+
426
+ /**
427
+ * Updates the metadata for a post
428
+ *
429
+ * @param int $id
430
+ * @param array $data
431
+ * @return int
432
+ */
433
+ protected function updatePostMeta($id, $data = array())
434
+ {
435
+ return update_post_meta($id, $this->metaKey, $data);
436
+ }
437
+
438
+ /**
439
+ * Deletes the metadata for a post
440
+ *
441
+ * @param int $id
442
+ * @return void
443
+ */
444
+ protected function deletePostMeta($id)
445
+ {
446
+ return delete_post_meta($id, $this->metaKey);
447
+ }
448
+
449
+ /**
450
+ * Gets the post type label
451
+ *
452
+ * @return string
453
+ */
454
+ abstract protected function getPostTypeLabel();
455
+
456
+ /**
457
+ * Gets a new model instance
458
+ *
459
+ * @return \EasingSlider\Foundation\Models\ModelContract
460
+ */
461
+ abstract protected function newModel();
462
+ }
src/Foundation/Shortcodes/Shortcode.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Shortcodes;
4
+
5
+ use EasingSlider\Foundation\Contracts\Shortcodes\Shortcode as ShortcodeContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Shortcode implements ShortcodeContract
15
+ {
16
+ /**
17
+ * Tag
18
+ *
19
+ * @var string
20
+ */
21
+ protected $tag;
22
+
23
+ /**
24
+ * Constructor
25
+ *
26
+ * @return void
27
+ */
28
+ public function __construct()
29
+ {
30
+ $this->defineHooks();
31
+ }
32
+
33
+ /**
34
+ * Define hooks
35
+ *
36
+ * @return void
37
+ */
38
+ protected function defineHooks()
39
+ {
40
+ add_shortcode($this->tag(), array($this, 'render'));
41
+ }
42
+
43
+ /**
44
+ * Returns the shortcode tag
45
+ *
46
+ * @return string
47
+ */
48
+ public function tag()
49
+ {
50
+ return $this->tag;
51
+ }
52
+
53
+ /**
54
+ * Renders the shortcode
55
+ *
56
+ * @param array $atts
57
+ * @return string
58
+ */
59
+ abstract public function render($atts = array());
60
+ }
src/Foundation/TemplateLoaders/TemplateLoader.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\TemplateLoaders;
4
+
5
+ use EasingSlider\Foundation\Contracts\TemplateLoaders\TemplateLoader as TemplateLoaderContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class TemplateLoader implements TemplateLoaderContract
15
+ {
16
+ /**
17
+ * Returns the path to the Easing Slider templates directory
18
+ *
19
+ * @return string
20
+ */
21
+ public function getTemplatesDir()
22
+ {
23
+ return EASINGSLIDER_TEMPLATES_DIR;
24
+ }
25
+
26
+ /**
27
+ * Returns the URL to the Easing Slider templates directory
28
+ *
29
+ * @return string
30
+ */
31
+ public function getTemplatesUrl()
32
+ {
33
+ return EASINGSLIDER_TEMPLATES_URL;
34
+ }
35
+
36
+ /**
37
+ * Retrieves a template part. Taken from bbPress and modified to suit.
38
+ *
39
+ * @param array $data The data to be inserted
40
+ * @param string $slug The template slug
41
+ * @param string $name The template name
42
+ * @param boolean $load Whether to load the template or return it
43
+ * @return string
44
+ */
45
+ public function getTemplatePart($data, $slug, $name = null, $load = true) {
46
+
47
+ // Execute code for this part
48
+ do_action("get_template_part_{$slug}", $slug, $name);
49
+
50
+ // Array of possible templates
51
+ $templates = array();
52
+
53
+ // Append template name to slug
54
+ if (isset($name)) {
55
+ $templates[] = "{$slug}-{$name}.php";
56
+ }
57
+
58
+ // Add to possible templates
59
+ $templates[] = "{$slug}.php";
60
+
61
+ // Allow template parts to be filtered
62
+ $templates = apply_filters('easingslider_get_template_part', $templates, $slug, $name);
63
+
64
+ // Return the part that is found
65
+ return $this->locateTemplate($data, $templates, $load, false);
66
+
67
+ }
68
+
69
+ /**
70
+ * Retrieve the name of the highest priority template file that exists.
71
+ *
72
+ * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which
73
+ * inherit from a parent theme can just overload one file. If the template is
74
+ * not found in either of those, it looks in the theme-compat folder last.
75
+ *
76
+ * Taken from bbPress.
77
+ *
78
+ * @param array $data Data inserted into the template.
79
+ * @param string|array $templateNames Template file(s) to search for, in order.
80
+ * @param bool $load If true the template file will be loaded if it is found.
81
+ * @param bool $requireOnce Whether to require_once or require. Default true. Has no effect if $load is false.
82
+ * @return string
83
+ */
84
+ public function locateTemplate($data, $templateNames, $load = false, $requireOnce = true)
85
+ {
86
+ // No file found yet
87
+ $located = false;
88
+
89
+ // Try to find a template file
90
+ foreach ((array) $templateNames as $templateName) {
91
+
92
+ // Continue if template is empty
93
+ if (empty($templateName)) {
94
+ continue;
95
+ }
96
+
97
+ // Trim off any slashes from the template name
98
+ $templateName = ltrim($templateName, '/');
99
+
100
+ // Try locating this template file by looping through the template paths
101
+ foreach ($this->getThemeTemplatePaths() as $templatePath) {
102
+ if (file_exists($templatePath . $templateName)) {
103
+ $located = $templatePath . $templateName;
104
+ break;
105
+ }
106
+ }
107
+
108
+ // Bail if we've located a template
109
+ if ($located) {
110
+ break;
111
+ }
112
+
113
+ }
114
+
115
+ /**
116
+ * Load the template if desired.
117
+ *
118
+ * Using our own `easingslider_load_template` function here to accommodate data insertion.
119
+ */
120
+ if ((true == $load) && ! empty($located)) {
121
+ easingslider_load_template($data, $located, $requireOnce);
122
+ }
123
+
124
+ return $located;
125
+ }
126
+
127
+ /**
128
+ * Returns a list of paths to check for template locations. Taken and modified from AffiliateWP.
129
+ *
130
+ * @return mixed|void
131
+ */
132
+ public function getThemeTemplatePaths() {
133
+
134
+ $templateDir = $this->getThemeTemplateDirName();
135
+
136
+ $filePaths = array(
137
+ 1 => trailingslashit(get_stylesheet_directory()) . $templateDir,
138
+ 10 => trailingslashit(get_template_directory()) . $templateDir,
139
+ 100 => $this->getTemplatesDir()
140
+ );
141
+
142
+ $filePaths = apply_filters('easingslider_template_paths', $filePaths);
143
+
144
+ // Sort the file paths based on priority
145
+ ksort($filePaths, SORT_NUMERIC);
146
+
147
+ return array_map('trailingslashit', $filePaths);
148
+
149
+ }
150
+
151
+ /**
152
+ * Returns the URL to the Easing Slider templates directory
153
+ *
154
+ * @return string
155
+ */
156
+ abstract public function getThemeTemplateDirName();
157
+ }
src/Foundation/Uninstallation/Uninstaller.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Uninstallation;
4
+
5
+ use EasingSlider\Foundation\Contracts\Uninstallation\Uninstaller as UninstallerContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ abstract class Uninstaller implements UninstallerContract
15
+ {
16
+ /**
17
+ * Executes uninstallation
18
+ *
19
+ * @return void
20
+ */
21
+ abstract public function uninstall();
22
+ }
src/Foundation/Widgets/Widget.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Foundation\Widgets;
4
+
5
+ use EasingSlider\Foundation\Contracts\Widgets\Widget as WidgetContract;
6
+ use WP_Widget;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class Widget extends WP_Widget implements WidgetContract
16
+ {
17
+ /**
18
+ * Constructor
19
+ *
20
+ * @return void
21
+ */
22
+ public function __construct()
23
+ {
24
+ // Boot, if method exists. Use this to set dependencies, as WordPress doesn't allow us to provide widget dependencies.
25
+ if (method_exists($this, 'boot')) {
26
+ $this->boot();
27
+ }
28
+
29
+ // Call parent constructor
30
+ parent::__construct(
31
+ $this->getName(),
32
+ $this->getTitle(),
33
+ array('description' => $this->getDescription())
34
+ );
35
+
36
+ // Register the widget
37
+ $this->register();
38
+ }
39
+
40
+ /**
41
+ * Registers the widget
42
+ *
43
+ * @return void
44
+ */
45
+ public function register()
46
+ {
47
+ $className = get_called_class();
48
+
49
+ add_action('widgets_init', function () use ($className) {
50
+ register_widget($className);
51
+ });
52
+ }
53
+
54
+ /**
55
+ * Widget logic
56
+ *
57
+ * @param array $args
58
+ * @param array $instance
59
+ * @return void
60
+ */
61
+ public function widget($args, $instance)
62
+ {
63
+ // Extract arguments
64
+ extract($args);
65
+
66
+ // Before widget
67
+ echo $before_widget;
68
+
69
+ // Display title
70
+ if ( ! empty($instance['title'])) {
71
+ echo $before_title . apply_filters('widgets_title', $instance['title']) . $after_title;
72
+ }
73
+
74
+ // Display the widget content
75
+ $this->display($instance);
76
+
77
+ // After widget
78
+ echo $after_widget;
79
+ }
80
+
81
+ /**
82
+ * Gets the widget name
83
+ *
84
+ * @return string
85
+ */
86
+ abstract protected function getName();
87
+
88
+ /**
89
+ * Gets the widget title
90
+ *
91
+ * @return string
92
+ */
93
+ abstract protected function getTitle();
94
+
95
+ /**
96
+ * Gets the widget description
97
+ *
98
+ * @return string
99
+ */
100
+ abstract protected function getDescription();
101
+
102
+ /**
103
+ * Displays the widget content
104
+ *
105
+ * @param array $instance
106
+ * @return void
107
+ */
108
+ abstract public function display($instance);
109
+ }
src/Foundation/helpers.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Exit if accessed directly
5
+ */
6
+ if ( ! defined('ABSPATH')) {
7
+ exit;
8
+ }
9
+
10
+ if ( ! function_exists('easingslider_is_admin')) {
11
+ /**
12
+ * Checks if the current page is one of our admin pages
13
+ *
14
+ * @return boolean
15
+ */
16
+ function easingslider_is_admin()
17
+ {
18
+ if (function_exists('get_current_screen')) {
19
+
20
+ // Get the current scren
21
+ $currentScreen = get_current_screen();
22
+
23
+ // Check current screen ID contains 'easingslider'
24
+ if (isset($currentScreen->id) && false !== strpos($currentScreen->id, 'easingslider')) {
25
+ return true;
26
+ }
27
+
28
+ }
29
+
30
+ return false;
31
+ }
32
+ }
33
+
34
+ if ( ! function_exists('easingslider_get_admin_page')) {
35
+ /**
36
+ * Gets the current admin page slug
37
+ *
38
+ * @return string|false
39
+ */
40
+ function easingslider_get_admin_page()
41
+ {
42
+ if (isset($_GET['page'])) {
43
+ return sanitize_key($_GET['page']);
44
+ }
45
+
46
+ return false;
47
+ }
48
+ }
49
+
50
+ if ( ! function_exists('easingslider_get_admin_page_id')) {
51
+ /**
52
+ * Gets the current admin page ID
53
+ *
54
+ * @return int|false
55
+ */
56
+ function easingslider_get_admin_page_id()
57
+ {
58
+ if (isset($_GET['edit'])) {
59
+ return absint($_GET['edit']);
60
+ }
61
+
62
+ return false;
63
+ }
64
+ }
65
+
66
+ if ( ! function_exists('easingslider_get_admin_base_url')) {
67
+ /**
68
+ * Gets the admin base url
69
+ *
70
+ * @return string|false
71
+ */
72
+ function easingslider_get_admin_base_url()
73
+ {
74
+ $baseUrl = parse_url(self_admin_url(), PHP_URL_PATH) . 'admin.php';
75
+
76
+ // Get parameters
77
+ $page = easingslider_get_admin_page();
78
+ $pageID = easingslider_get_admin_page_id();
79
+
80
+ // Bail if we don't have a page
81
+ if ( ! $page) {
82
+ return false;
83
+ }
84
+
85
+ // Get the URL with page parameter
86
+ $baseUrl = add_query_arg('page', $page, $baseUrl);
87
+
88
+ // Add optional page ID
89
+ if ($pageID) {
90
+ $baseUrl = add_query_arg('edit', $pageID, $baseUrl);
91
+ }
92
+
93
+ return esc_url(str_replace('/wp-admin/', '', $baseUrl));
94
+ }
95
+ }
96
+
97
+ if ( ! function_exists('easingslider_locate_template')) {
98
+ /**
99
+ * Copy of WordPress's `load_template` function, with alterations to allow for data insertion.
100
+ *
101
+ * @param array $data The data to be inserted.
102
+ * @param string $_template_file Path to template file.
103
+ * @param bool $require_once Whether to require_once or require. Default true.
104
+ */
105
+ function easingslider_load_template($data, $_template_file, $require_once = true)
106
+ {
107
+ global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
108
+
109
+ if (is_array($data)) {
110
+ extract($data);
111
+ }
112
+
113
+ if (is_array($wp_query->query_vars)) {
114
+ extract($wp_query->query_vars, EXTR_SKIP);
115
+ }
116
+
117
+ if (isset($s)) {
118
+ $s = esc_attr($s);
119
+ }
120
+
121
+ if ($require_once) {
122
+ require_once($_template_file);
123
+ } else {
124
+ require($_template_file);
125
+ }
126
+ }
127
+ }
src/Plugin/Activation/Activator.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Activation;
4
+
5
+ use EasingSlider\Foundation\Activation\Activator as BaseActivator;
6
+ use EasingSlider\Foundation\Contracts\Capabilities\Capabilities;
7
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ class Activator extends BaseActivator
17
+ {
18
+ /**
19
+ * Capabilities
20
+ *
21
+ * @var \EasingSlider\Foundation\Contracts\Capabilities\Capabilities
22
+ */
23
+ protected $capabilities;
24
+
25
+ /**
26
+ * Sliders
27
+ *
28
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
29
+ */
30
+ protected $sliders;
31
+
32
+ /**
33
+ * Constructor
34
+ *
35
+ * @param \EasingSlider\Foundation\Contracts\Capabilities\Capabilities $capabilities
36
+ * @param \EasingSlider\Foundation\Contracts\Repositories\Repository $sliders
37
+ * @return void
38
+ */
39
+ public function __construct(Capabilities $capabilities, Repository $sliders)
40
+ {
41
+ $this->capabilities = $capabilities;
42
+ $this->sliders = $sliders;
43
+ }
44
+
45
+ /**
46
+ * Checks our require and deactivates the plugin if those requirements aren't met.
47
+ *
48
+ * @return void
49
+ */
50
+ protected function checkRequirements()
51
+ {
52
+ global $wp_version;
53
+
54
+ // Deactivate the plugin if using less than PHP 5.3.
55
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
56
+ deactivate_plugins(plugin_basename(EASINGSLIDER_PLUGIN_FILE));
57
+ wp_die(sprintf(__('Sorry, but your version of PHP (v%s) is not supported. PHP v5.3.0 or greater is required. The plugin has been deactivated. <a href="%s">Return to the Dashboard.</a>', 'easingslider'), PHP_VERSION, admin_url()));
58
+ exit();
59
+ }
60
+
61
+ // Deactivate the plugin if the WordPress version is below the minimum required.
62
+ if (version_compare($wp_version, '4.5', '<')) {
63
+ deactivate_plugins(plugin_basename(EASINGSLIDER_PLUGIN_FILE));
64
+ wp_die(sprintf(__('Sorry, but your version of WordPress, <strong>%s</strong>, is not supported. The plugin has been deactivated. <a href="%s">Return to the Dashboard.</a>', 'easingslider'), $wp_version, admin_url()));
65
+ exit();
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Creates our capabilities
71
+ *
72
+ * @return void
73
+ */
74
+ protected function createCapabilities()
75
+ {
76
+ $this->capabilities->addToRoles();
77
+ }
78
+
79
+ /**
80
+ * Recreate our rewrite rules to avoid issues with any custom post types.
81
+ *
82
+ * To ensure rules are correctly flushed, we have to register our custom post type(s) here.
83
+ * This is because the `init` hook has fired before the plugin was activated internally.
84
+ *
85
+ * Don't like this approach. I'd prefer to have the plugin make no assumptions
86
+ * about the repository, but this is the simplest solution.
87
+ *
88
+ * Ensure that you don't get caught out in future here if changing a repository from
89
+ * a post type to a custom database table.
90
+ *
91
+ * @return void
92
+ */
93
+ protected function flushRewriteRules()
94
+ {
95
+ $this->sliders->registerPostType();
96
+
97
+ flush_rewrite_rules();
98
+ }
99
+
100
+ /**
101
+ * Executes activation
102
+ *
103
+ * @return void
104
+ */
105
+ public function activate()
106
+ {
107
+ $this->checkRequirements();
108
+
109
+ $this->createCapabilities();
110
+
111
+ $this->flushRewriteRules();
112
+ }
113
+ }
src/Plugin/Admin/Actions/Addons.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Actions;
4
+
5
+ use EasingSlider\Foundation\Admin\Actions\Actions;
6
+ use EasingSlider\Foundation\Contracts\Admin\LicenseHandlers\LicenseHandler;
7
+ use EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler;
8
+ use EasingSlider\Plugin\Admin\Validators\License as LicenseValidator;
9
+
10
+ /**
11
+ * Exit if accessed directly
12
+ */
13
+ if ( ! defined('ABSPATH')) {
14
+ exit;
15
+ }
16
+
17
+ class Addons extends Actions
18
+ {
19
+ /**
20
+ * License Handler
21
+ *
22
+ * @var \EasingSlider\Foundation\Contracts\Admin\LicenseHandlers\LicenseHandler
23
+ */
24
+ protected $licenseHandler;
25
+
26
+ /**
27
+ * Constructor
28
+ *
29
+ * @param \EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler $notices
30
+ * @param \EasingSlider\Foundation\Contracts\Admin\LicenseHandlers\LicenseHandler $license
31
+ * @return void
32
+ */
33
+ public function __construct(NoticeHandler $notices, LicenseHandler $licenseHandler)
34
+ {
35
+ $this->licenseHandler = $licenseHandler;
36
+
37
+ parent::__construct($notices);
38
+ }
39
+
40
+ /**
41
+ * Defines our actions
42
+ *
43
+ * @return void
44
+ */
45
+ protected function defineActions()
46
+ {
47
+ add_action('easingslider_activate_license', array($this, 'activateLicense'));
48
+ add_action('easingslider_deactivate_license', array($this, 'deactivateLicense'));
49
+ }
50
+
51
+ /**
52
+ * Gets a new validator instance
53
+ *
54
+ * @return array
55
+ */
56
+ protected function validator()
57
+ {
58
+ return new LicenseValidator();
59
+ }
60
+
61
+ /**
62
+ * Activates a license key
63
+ *
64
+ * @param array $data
65
+ * @return void
66
+ */
67
+ public function activateLicense($data = array())
68
+ {
69
+ // Check that license key has been entered
70
+ if ( ! empty($data['license_key'])) {
71
+
72
+ // Set the license key
73
+ $this->licenseHandler->setKey(trim($data['license_key']));
74
+
75
+ // Activate the license
76
+ $response = $this->licenseHandler->activate();
77
+
78
+ // Show response
79
+ if ($response) {
80
+ if ( ! empty($response->success)) {
81
+
82
+ // Set the license status
83
+ $this->licenseHandler->setStatus('valid');
84
+
85
+ // Clear addons cache
86
+ delete_site_transient('easingslider_addons');
87
+
88
+ // Tell the user we've activated the license
89
+ $this->notices->success('license_activated', $response->message);
90
+
91
+ } else {
92
+
93
+ // Tell the user we've had an error
94
+ $this->notices->error('license_activation_failed', $response->message);
95
+
96
+ }
97
+ }
98
+
99
+ } else {
100
+
101
+ // Tell user to enter a license key
102
+ $this->notices->error('enter_license', __('Please enter a license key.', 'easingslider'));
103
+
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Deactivates a license key
109
+ *
110
+ * @param array $data
111
+ * @return void
112
+ */
113
+ public function deactivateLicense($data = array())
114
+ {
115
+ // Deactivate the license
116
+ $response = $this->licenseHandler->deactivate();
117
+
118
+ // Show response
119
+ if ( ! empty($response->success)) {
120
+
121
+ // Reset the license key & status
122
+ $this->licenseHandler->setKey('');
123
+ $this->licenseHandler->setStatus('');
124
+
125
+ // Clear addons cache
126
+ delete_site_transient('easingslider_addons');
127
+
128
+ // Tell the user the license has been deactivated
129
+ $this->notices->success('license_deactivated', $response->message);
130
+
131
+ } else {
132
+
133
+ // Tell the user we've had an error
134
+ $this->notices->error('license_deactivation_failed', $response->message);
135
+
136
+ }
137
+ }
138
+ }
src/Plugin/Admin/Actions/Processor.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Actions;
4
+
5
+ use EasingSlider\Foundation\Admin\Actions\Processor as BaseProcessor;
6
+ use EasingSlider\Plugin\Admin\Actions\SettingsActions;
7
+ use EasingSlider\Plugin\Admin\Actions\SliderActions;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ class Processor extends BaseProcessor
17
+ {
18
+ /**
19
+ * Boot
20
+ *
21
+ * @return void
22
+ */
23
+ protected function boot()
24
+ {
25
+ $this->actions['addons'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Actions\Addons');
26
+ $this->actions['settings'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Actions\Settings');
27
+ $this->actions['sliders'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Actions\Sliders');
28
+ }
29
+ }
src/Plugin/Admin/Actions/Settings.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Actions;
4
+
5
+ use EasingSlider\Foundation\Admin\Actions\Actions;
6
+ use EasingSlider\Foundation\Contracts\Activation\Activator;
7
+ use EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler;
8
+ use EasingSlider\Foundation\Contracts\Uninstallation\Uninstaller;
9
+ use EasingSlider\Plugin\Admin\Validators\Settings as SettingsValidator;
10
+
11
+ /**
12
+ * Exit if accessed directly
13
+ */
14
+ if ( ! defined('ABSPATH')) {
15
+ exit;
16
+ }
17
+
18
+ class Settings extends Actions
19
+ {
20
+ /**
21
+ * Activator
22
+ *
23
+ * @var \EasingSlider\Foundation\Contracts\Activation\Activator
24
+ */
25
+ protected $activator;
26
+
27
+ /**
28
+ * Uninstaller
29
+ *
30
+ * @var \EasingSlider\Foundation\Contracts\Uninstallation\Uninstaller
31
+ */
32
+ protected $uninstaller;
33
+
34
+ /**
35
+ * Constructor
36
+ *
37
+ * @param \EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler $notices
38
+ * @param \EasingSlider\Foundation\Contracts\Activation\Activator $activator
39
+ * @param \EasingSlider\Foundation\Contracts\Uninstallation\Uninstaller $uninstaller
40
+ * @return void
41
+ */
42
+ public function __construct(NoticeHandler $notices, Activator $activator, Uninstaller $uninstaller)
43
+ {
44
+ $this->activator = $activator;
45
+ $this->uninstaller = $uninstaller;
46
+
47
+ parent::__construct($notices);
48
+ }
49
+
50
+ /**
51
+ * Defines our actions
52
+ *
53
+ * @return void
54
+ */
55
+ protected function defineActions()
56
+ {
57
+ add_action('easingslider_reset_plugin', array($this, 'resetPlugin'));
58
+ }
59
+
60
+ /**
61
+ * Gets a new validator instance
62
+ *
63
+ * @return array
64
+ */
65
+ protected function validator()
66
+ {
67
+ return new SettingsValidator();
68
+ }
69
+
70
+ /**
71
+ * Resets the plugin by doing an uninstall then running an activation sequence
72
+ *
73
+ * @return void
74
+ */
75
+ public function resetPlugin()
76
+ {
77
+ // Run an uninstallation
78
+ $this->uninstaller->uninstall();
79
+
80
+ // Run an activation
81
+ $this->activator->activate();
82
+
83
+ // Redirect back to settings page to avoid resetting the plugin again if the user refreshes the page.
84
+ wp_safe_redirect( "admin.php?page=easingslider-settings&easingslider_notice=reset_plugin" );
85
+ exit();
86
+ }
87
+ }
src/Plugin/Admin/Actions/Sliders.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Actions;
4
+
5
+ use EasingSlider\Foundation\Admin\Actions\ResourceActions;
6
+ use EasingSlider\Plugin\Admin\Validators\Slider as SliderValidator;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class Sliders extends ResourceActions
16
+ {
17
+ /**
18
+ * Action Suffix
19
+ *
20
+ * @var string
21
+ */
22
+ protected $actionSuffix = 'slider';
23
+
24
+ /**
25
+ * Gets the permissions for our security checks
26
+ *
27
+ * @return array
28
+ */
29
+ protected function getPermissions()
30
+ {
31
+ return apply_filters('easingslider_admin_slider_permissions', array(
32
+ 'create' => 'easingslider_publish_sliders',
33
+ 'update' => 'easingslider_edit_sliders',
34
+ 'duplicate' => 'easingslider_duplicate_sliders',
35
+ 'trash' => 'easingslider_delete_sliders',
36
+ 'untrash' => 'easingslider_delete_sliders',
37
+ 'delete' => 'easingslider_delete_sliders'
38
+ ));
39
+ }
40
+
41
+ /**
42
+ * Gets the messages for our notices
43
+ *
44
+ * @return array
45
+ */
46
+ protected function getMessages()
47
+ {
48
+ return apply_filters('easingslider_admin_slider_messages', array(
49
+ 'created' => __('Slider has been published successfully.', 'easingslider'),
50
+ 'updated' => __('Slider has been saved successfully.', 'easingslider'),
51
+ 'duplicated' => __('Slider(s) duplicated successfully', 'easingslider'),
52
+ 'trashed' => __('Slider(s) moved to the Trash.', 'easingslider'),
53
+ 'untrashed' => __('Slider(s) restored successfully.', 'easingslider'),
54
+ 'deleted' => __('Slider(s) deleted permanently.', 'easingslider')
55
+ ));
56
+ }
57
+
58
+ /**
59
+ * Redirects to the resource editor after creation
60
+ *
61
+ * @param int $id
62
+ * @return void
63
+ */
64
+ protected function creationRedirect($id)
65
+ {
66
+ wp_safe_redirect("admin.php?page=easingslider&edit={$id}&easingslider_notice=publish_slider");
67
+ exit();
68
+ }
69
+
70
+ /**
71
+ * Gets a new validator instance
72
+ *
73
+ * @return array
74
+ */
75
+ protected function validator()
76
+ {
77
+ return new SliderValidator();
78
+ }
79
+ }
src/Plugin/Admin/AddonUpdater.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin;
4
+
5
+ use EasingSlider\Foundation\Admin\PluginUpdaters\PluginUpdater;
6
+ use EasingSlider\Plugin\Contracts\Options\License;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ // Uncomment for testing
16
+ // set_site_transient('update_plugins', null);
17
+
18
+ class AddonUpdater extends PluginUpdater
19
+ {
20
+ /**
21
+ * Constructor
22
+ *
23
+ * @param \EasingSlider\Plugin\Contracts\Options\License $license
24
+ * @param string $name
25
+ * @param string $file
26
+ * @param string $version
27
+ * @return void
28
+ */
29
+ public function __construct(License $license, $name, $file, $version)
30
+ {
31
+ parent::__construct($license, $name, $file, $version);
32
+ }
33
+
34
+ /**
35
+ * Gets the latest plugin version
36
+ *
37
+ * @return object|false
38
+ */
39
+ protected function getLatestVersion()
40
+ {
41
+ $requestParams = array(
42
+ 'easingslider_action' => 'addon_version',
43
+ 'license' => $this->license['key'],
44
+ 'name' => $this->name,
45
+ 'slug' => $this->pluginSlug,
46
+ 'url' => home_url()
47
+ );
48
+
49
+ // Get response from API
50
+ $response = wp_remote_post(
51
+ $this->getApiUrl(),
52
+ array(
53
+ 'timeout' => 15,
54
+ 'sslverify' => false,
55
+ 'body' => $requestParams
56
+ )
57
+ );
58
+
59
+ // Check for WordPress error(s)
60
+ if (is_wp_error($response)) {
61
+ return false;
62
+ }
63
+
64
+ // Get reponse body
65
+ $data = json_decode(wp_remote_retrieve_body($response));
66
+
67
+ // Bail if we got no response body
68
+ if (is_null($data)) {
69
+ return false;
70
+ }
71
+
72
+ // Unserialize sections
73
+ if (isset($data->sections)) {
74
+ $data->sections = maybe_unserialize($data->sections);
75
+ }
76
+
77
+ return $data;
78
+ }
79
+ }
src/Plugin/Admin/Admin.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin;
4
+
5
+ use EasingSlider\Foundation\Admin\Admin as BaseAdmin;
6
+ use EasingSlider\Foundation\Contracts\Plugin;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class Admin extends BaseAdmin
16
+ {
17
+ /**
18
+ * Admin Prefix
19
+ *
20
+ * @var string
21
+ */
22
+ protected $prefix = 'easingslider';
23
+
24
+ /**
25
+ * Actions
26
+ *
27
+ * @var \EasingSlider\Foundation\Contracts\Admin\Actions\Processor
28
+ */
29
+ protected $actions;
30
+
31
+ /**
32
+ * Ajax
33
+ *
34
+ * @var \EasingSlider\Foundation\Contracts\Admin\Ajax\Router
35
+ */
36
+ protected $ajax;
37
+
38
+ /**
39
+ * Assets
40
+ *
41
+ * @var \EasingSlider\Foundation\Contracts\Admin\Assets\Assets
42
+ */
43
+ protected $assets;
44
+
45
+ /**
46
+ * License Handler
47
+ *
48
+ * @var \EasingSlider\Plugin\Contracts\Admin\LicenseHandler
49
+ */
50
+ protected $licenseHandler;
51
+
52
+ /**
53
+ * Media Button
54
+ *
55
+ * @var \EasingSlider\Plugin\Admin\MediaButton
56
+ */
57
+ protected $mediaButton;
58
+
59
+ /**
60
+ * Menu
61
+ *
62
+ * @var \EasingSlider\Foundation\Contracts\Admin\Menus\Menu
63
+ */
64
+ protected $menu;
65
+
66
+ /**
67
+ * Notices
68
+ *
69
+ * @var \EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler
70
+ */
71
+ protected $notices;
72
+
73
+ /**
74
+ * Upgrades
75
+ *
76
+ * @var \EasingSlider\Foundation\Contracts\Admin\Upgrades\Upgrades
77
+ */
78
+ protected $upgrades;
79
+
80
+ /**
81
+ * Aliases
82
+ *
83
+ * @var array
84
+ */
85
+ protected $aliases = array(
86
+ '\EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler' => '\EasingSlider\Foundation\Admin\Notices\NoticeHandler',
87
+ '\EasingSlider\Foundation\Contracts\Admin\Actions\Processor' => '\EasingSlider\Plugin\Admin\Actions\Processor',
88
+ '\EasingSlider\Foundation\Contracts\Admin\Admin' => '\EasingSlider\Plugin\Admin\Admin',
89
+ '\EasingSlider\Foundation\Contracts\Admin\Ajax\Router' => '\EasingSlider\Plugin\Admin\Ajax\Router',
90
+ '\EasingSlider\Foundation\Contracts\Admin\Assets\Assets' => '\EasingSlider\Plugin\Admin\Assets\Assets',
91
+ '\EasingSlider\Foundation\Contracts\Admin\LicenseHandlers\LicenseHandler' => '\EasingSlider\Plugin\Admin\LicenseHandler',
92
+ '\EasingSlider\Foundation\Contracts\Admin\Menus\Menu' => '\EasingSlider\Plugin\Admin\Menus\Menu',
93
+ '\EasingSlider\Foundation\Contracts\Admin\Panels\Panels' => '\EasingSlider\Plugin\Admin\Panels\Panels',
94
+ '\EasingSlider\Foundation\Contracts\Admin\PluginUpdaters\PluginUpdater' => '\EasingSlider\Plugin\Admin\AddonUpdater',
95
+ '\EasingSlider\Foundation\Contracts\Admin\Upgrades\Upgrades' => '\EasingSlider\Plugin\Admin\Upgrades\Upgrades',
96
+ '\EasingSlider\Plugin\Contracts\Admin\Validators\License' => '\EasingSlider\Plugin\Admin\Validators\License',
97
+ '\EasingSlider\Plugin\Contracts\Admin\Validators\Settings' => '\EasingSlider\Plugin\Admin\Validators\Settings',
98
+ '\EasingSlider\Plugin\Contracts\Admin\Validators\Slider' => '\EasingSlider\Plugin\Admin\Validators\Slider'
99
+ );
100
+
101
+ /**
102
+ * Singletons
103
+ *
104
+ * @var array
105
+ */
106
+ protected $singletons = array(
107
+ '\EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler',
108
+ '\EasingSlider\Foundation\Contracts\Admin\Actions\Processor',
109
+ '\EasingSlider\Foundation\Contracts\Admin\Ajax\Router',
110
+ '\EasingSlider\Foundation\Contracts\Admin\Assets\Assets',
111
+ '\EasingSlider\Foundation\Contracts\Admin\LicenseHandlers\LicenseHandler',
112
+ '\EasingSlider\Foundation\Contracts\Admin\Menus\Menu',
113
+ '\EasingSlider\Foundation\Contracts\Admin\Panels\Panels',
114
+ '\EasingSlider\Foundation\Contracts\Admin\Upgrades\Upgrades'
115
+ );
116
+
117
+ /**
118
+ * Boot
119
+ *
120
+ * @return void
121
+ */
122
+ protected function boot()
123
+ {
124
+ $this->actions = $this->plugin->make('\EasingSlider\Foundation\Contracts\Admin\Actions\Processor');
125
+ $this->ajax = $this->plugin->make('\EasingSlider\Foundation\Contracts\Admin\Ajax\Router');
126
+ $this->assets = $this->plugin->make('\EasingSlider\Foundation\Contracts\Admin\Assets\Assets');
127
+ $this->licenseHandler = $this->plugin->make('\EasingSlider\Foundation\Contracts\Admin\LicenseHandlers\LicenseHandler');
128
+ $this->mediaButton = $this->plugin->make('\EasingSlider\Plugin\Admin\MediaButton');
129
+ $this->menu = $this->plugin->make('\EasingSlider\Foundation\Contracts\Admin\Menus\Menu');
130
+ $this->notices = $this->plugin->make('\EasingSlider\Foundation\Contracts\Admin\Notices\NoticeHandler');
131
+ $this->upgrades = $this->plugin->make('\EasingSlider\Foundation\Contracts\Admin\Upgrades\Upgrades');
132
+ }
133
+ }
src/Plugin/Admin/Ajax/AddonActivator.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Ajax;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ class AddonActivator
13
+ {
14
+ /**
15
+ * Activates an addon
16
+ *
17
+ * @return array|false
18
+ */
19
+ public function activate()
20
+ {
21
+ // Do security check
22
+ check_ajax_referer('easingslider-activate-addon', 'nonce');
23
+
24
+ // Activate addon (just a WordPress plugin)
25
+ if (isset($_POST['plugin'])) {
26
+
27
+ // Attempt activation
28
+ $activation = activate_plugin($_POST['plugin']);
29
+
30
+ // Handle errors
31
+ if (is_wp_error($activation)) {
32
+ return array('error' => $activation->get_error_message());
33
+ }
34
+
35
+ return true;
36
+
37
+ }
38
+
39
+ return false;
40
+ }
41
+ }
src/Plugin/Admin/Ajax/AddonDeactivator.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Ajax;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ class AddonDeactivator
13
+ {
14
+ /**
15
+ * Deactivates an addon
16
+ *
17
+ * @return array|false
18
+ */
19
+ public function deactivate()
20
+ {
21
+ // Do security check
22
+ check_ajax_referer('easingslider-deactivate-addon', 'nonce');
23
+
24
+ // Deactivate addon (just a WordPress plugin)
25
+ if (isset($_POST['plugin'])) {
26
+
27
+ // Attempt deactivation (provides no response so assume it worked)
28
+ deactivate_plugins($_POST['plugin']);
29
+
30
+ return true;
31
+
32
+ }
33
+
34
+ return false;
35
+ }
36
+ }
src/Plugin/Admin/Ajax/AddonInstaller.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Ajax;
4
+
5
+ use EasingSlider\Plugin\Admin\UpgraderSkin;
6
+ use Plugin_Upgrader;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class AddonInstaller
16
+ {
17
+ /**
18
+ * Installs an addon
19
+ *
20
+ * @return array|false
21
+ */
22
+ public function install()
23
+ {
24
+ global $hook_suffix;
25
+
26
+ // Do security check
27
+ check_ajax_referer('easingslider-install-addon', 'nonce');
28
+
29
+ // Install the addon
30
+ if (isset($_POST['plugin'])) {
31
+
32
+ // Get the download URL
33
+ $downloadUrl = $_POST['plugin'];
34
+
35
+ // Set the current screen to avoid undefined notices
36
+ set_current_screen();
37
+
38
+ // Prepare variables
39
+ $method = '';
40
+
41
+ // Get URL
42
+ $url = esc_url(add_query_arg(
43
+ array(
44
+ 'page' => 'easingslider-settings'
45
+ ),
46
+ admin_url('admin.php')
47
+ ));
48
+
49
+ // Start output bufferring to catch the filesystem form if credentials are needed
50
+ ob_start();
51
+ if (false === ($credentials = request_filesystem_credentials($url, $method, false, false, null))) {
52
+ $form = ob_get_clean();
53
+
54
+ return array('form' => $form);
55
+ }
56
+
57
+ // If we are not authenticated, make it happen now
58
+ if ( ! WP_Filesystem($credentials)) {
59
+ ob_start();
60
+ request_filesystem_credentials($url, $method, true, false, null);
61
+ $form = ob_get_clean();
62
+
63
+ return array('form' => $form);
64
+ }
65
+
66
+ // We do not need any extra credentials if we have gotten this far, so let's install the plugin
67
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
68
+
69
+ // Create the plugin upgrader with our custom skin
70
+ $installer = new Plugin_Upgrader(new UpgraderSkin());
71
+ $installer->install($downloadUrl);
72
+
73
+ // Flush the cache and return the newly installed plugin basename.
74
+ wp_cache_flush();
75
+ if ($installer->plugin_info()) {
76
+ $pluginBasename = $installer->plugin_info();
77
+
78
+ return array('plugin' => $pluginBasename);
79
+ }
80
+ }
81
+
82
+ return false;
83
+ }
84
+ }
src/Plugin/Admin/Ajax/Router.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Ajax;
4
+
5
+ use EasingSlider\Foundation\Admin\Ajax\Router as BaseRouter;
6
+ use EasingSlider\Plugin\Admin\Ajax\AddonActivator;
7
+ use EasingSlider\Plugin\Admin\Ajax\AddonDeactivator;
8
+ use EasingSlider\Plugin\Admin\Ajax\AddonInstaller;
9
+
10
+ /**
11
+ * Exit if accessed directly
12
+ */
13
+ if ( ! defined('ABSPATH')) {
14
+ exit;
15
+ }
16
+
17
+ class Router extends BaseRouter
18
+ {
19
+ /**
20
+ * Define hooks
21
+ *
22
+ * @return void
23
+ */
24
+ protected function defineHooks()
25
+ {
26
+ $this->setAction('easingslider_activate_addon', array($this, 'activateAddon'));
27
+ $this->setAction('easingslider_deactivate_addon', array($this, 'deactivateAddon'));
28
+ $this->setAction('easingslider_install_addon', array($this, 'installAddon'));
29
+ }
30
+
31
+ /**
32
+ * Activates an addon
33
+ *
34
+ * @return void
35
+ */
36
+ public function activateAddon()
37
+ {
38
+ $activator = new AddonActivator();
39
+
40
+ $response = $activator->activate();
41
+
42
+ if (false === $response) {
43
+ $this->response(true);
44
+ } else {
45
+ $this->response($response);
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Deactivates an addon
51
+ *
52
+ * @return void
53
+ */
54
+ public function deactivateAddon()
55
+ {
56
+ $deactivator = new AddonDeactivator();
57
+
58
+ $response = $deactivator->deactivate();
59
+
60
+ if (false === $response) {
61
+ $this->response(true);
62
+ } else {
63
+ $this->response($response);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Installs an addon
69
+ *
70
+ * @return void
71
+ */
72
+ public function installAddon()
73
+ {
74
+ $installer = new AddonInstaller();
75
+
76
+ $response = $installer->install();
77
+
78
+ if (false === $response) {
79
+ $this->response(true);
80
+ } else {
81
+ $this->response($response);
82
+ }
83
+ }
84
+ }
src/Plugin/Admin/Assets/Assets.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Assets;
4
+
5
+ use EasingSlider\Foundation\Admin\Assets\Assets as BaseAssets;
6
+ use EasingSlider\Foundation\Contracts\Admin\Menus\Menu;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class Assets extends BaseAssets
16
+ {
17
+ /**
18
+ * Menu
19
+ *
20
+ * @var \EasingSlider\Foundation\Contracts\Admin\Menus\Menu
21
+ */
22
+ protected $menu;
23
+
24
+ /**
25
+ * Constructor
26
+ *
27
+ * @param \EasingSlider\Foundation\Contracts\Admin\Menus\Menu $menu
28
+ * @return void
29
+ */
30
+ public function __construct(Menu $menu)
31
+ {
32
+ $this->menu = $menu;
33
+
34
+ $this->defineHooks();
35
+ }
36
+
37
+ /**
38
+ * Define hooks
39
+ *
40
+ * @return void
41
+ */
42
+ protected function defineHooks()
43
+ {
44
+ add_action('admin_enqueue_scripts', array($this, 'handleEnqueue'));
45
+ }
46
+
47
+ /**
48
+ * Handles enqueue on appropriate panels
49
+ *
50
+ * @param string $currentHookSuffix
51
+ * @return void
52
+ */
53
+ public function handleEnqueue($currentHookSuffix)
54
+ {
55
+ // Only enqueue assets on our admin submenus
56
+ foreach ($this->menu->submenus as $hookSuffix) {
57
+ if ($currentHookSuffix == $hookSuffix) {
58
+ $this->enqueue();
59
+ }
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Enqueues the localizations
65
+ *
66
+ * @return void
67
+ */
68
+ public function enqueueLocalizations()
69
+ {
70
+ $localizations = apply_filters('easingslider_admin_localizations', array(
71
+ 'warn' => __('Are you sure you wish to do this? This cannot be reversed.', 'easingslider'),
72
+ 'admin_url' => parse_url(self_admin_url(), PHP_URL_PATH),
73
+ 'plugin_url' => EASINGSLIDER_PLUGIN_URL,
74
+ 'base_url' => easingslider_get_admin_base_url(),
75
+ 'delete_slide' => __('Are you sure you wish to delete this slide? This cannot be reversed.', 'easingslider'),
76
+ 'delete_slides' => __('Are you sure you wish to delete all of this slider\'s images? This cannot be reversed.', 'easingslider'),
77
+ 'media_upload' => array(
78
+ 'title' => __('Edit Slide', 'easingslider'),
79
+ 'back' => __('Back', 'easingslider'),
80
+ 'update' => __('Update', 'easingslider'),
81
+ 'replace' => __('Replace', 'easingslider'),
82
+ 'replace_image' => __('Replace Image', 'easingslider'),
83
+ 'image_from_media' => __('Image from Media', 'easingslider'),
84
+ 'insert_into_slider' => __('Insert into Slider', 'easingslider')
85
+ ),
86
+ 'buttons' => array(
87
+ 'activate' => __('Activate Addon', 'easingslider'),
88
+ 'deactivate' => __('Deactivate Addon', 'easingslider'),
89
+ 'activating' => __('Activating...', 'easingslider'),
90
+ 'deactivating' => __('Deactivating...', 'easingslider'),
91
+ 'installing' => __('Installing...', 'easingslider')
92
+ ),
93
+ 'messages' => array(
94
+ 'active' => __('Status: Active', 'easingslider'),
95
+ 'inactive' => __('Status: Inactive', 'easingslider')
96
+ ),
97
+ 'nonces' => array(
98
+ 'activate' => wp_create_nonce('easingslider-activate-addon'),
99
+ 'deactivate' => wp_create_nonce('easingslider-deactivate-addon'),
100
+ 'install' => wp_create_nonce('easingslider-install-addon')
101
+ )
102
+ ));
103
+
104
+ // Load localizations
105
+ wp_localize_script('easingslider-admin', '_easingsliderAdminL10n', $localizations);
106
+ }
107
+
108
+ /**
109
+ * Enqueues the Backbone.js templates
110
+ *
111
+ * @return void
112
+ */
113
+ public function enqueueBackboneTemplates()
114
+ {
115
+ require EASINGSLIDER_RESOURCES_DIR . 'backbone/tmpl-edit-slide-frame.php';
116
+ require EASINGSLIDER_RESOURCES_DIR . 'backbone/tmpl-edit-slide.php';
117
+ require EASINGSLIDER_RESOURCES_DIR . 'backbone/tmpl-slide.php';
118
+
119
+ // Trigger hooks
120
+ do_action('easingslider_admin_backbone_templates');
121
+ }
122
+
123
+ /**
124
+ * Enqueues the assets
125
+ *
126
+ * @return void
127
+ */
128
+ public function enqueue()
129
+ {
130
+ $suffix = $this->getSuffix();
131
+
132
+ // Enqueue WordPress Media
133
+ wp_enqueue_media();
134
+
135
+ // Load assets
136
+ wp_enqueue_style('easingslider-admin', EASINGSLIDER_ASSETS_URL . "css/admin{$suffix}.css", false, EASINGSLIDER_VERSION);
137
+ wp_enqueue_script('easingslider-admin', EASINGSLIDER_ASSETS_URL . "js/admin{$suffix}.js", array('jquery', 'jquery-ui-sortable', 'backbone', 'media-grid'), EASINGSLIDER_VERSION);
138
+
139
+ // Load localizations
140
+ $this->enqueueLocalizations();
141
+
142
+ // Load backbone.js templates
143
+ add_action('admin_footer', array($this, 'enqueueBackboneTemplates'));
144
+
145
+ // Trigger hooks
146
+ do_action('easingslider_admin_enqueue_assets', $suffix);
147
+ }
148
+ }
src/Plugin/Admin/LicenseHandler.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin;
4
+
5
+ use EasingSlider\Foundation\Admin\LicenseHandlers\EDDLicenseHandler;
6
+ use EasingSlider\Plugin\Contracts\Options\License;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class LicenseHandler extends EDDLicenseHandler
16
+ {
17
+ /**
18
+ * Constructor
19
+ *
20
+ * @param \EasingSlider\Plugin\Contracts\Options\License $license
21
+ * @return void
22
+ */
23
+ public function __construct(License $license)
24
+ {
25
+ parent::__construct(
26
+ $license,
27
+ EASINGSLIDER_NAME,
28
+ EASINGSLIDER_PLUGIN_FILE,
29
+ EASINGSLIDER_VERSION
30
+ );
31
+ }
32
+ }
src/Plugin/Admin/ListTables/Sliders.php ADDED
@@ -0,0 +1,533 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\ListTables;
4
+
5
+ use EasingSlider\Foundation\Admin\ListTables\ListTable;
6
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
7
+ use EasingSlider\Foundation\Contracts\Shortcodes\Shortcode;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ class Sliders extends ListTable
17
+ {
18
+ /**
19
+ * Shortcode
20
+ *
21
+ * @var \EasingSlider\Foundation\Contracts\Shortcodes\Shortcode
22
+ */
23
+ protected $shortcode;
24
+
25
+ /**
26
+ * Sliders
27
+ *
28
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
29
+ */
30
+ protected $sliders;
31
+
32
+ /**
33
+ * Page Slug
34
+ *
35
+ * @var string|false
36
+ */
37
+ protected $page;
38
+
39
+ /**
40
+ * Constructor
41
+ *
42
+ * @param \EasingSlider\Foundation\Contracts\Repositories\Repository $sliders
43
+ * @param \EasingSlider\Foundation\Contracts\Shortcodes\Shortcode $shortcode
44
+ * @return void
45
+ */
46
+ public function __construct(Repository $sliders, Shortcode $shortcode)
47
+ {
48
+ $this->sliders = $sliders;
49
+ $this->shortcode = $shortcode;
50
+
51
+ // Get page
52
+ $this->page = $this->getPage();
53
+
54
+ // Call parent
55
+ parent::__construct( array(
56
+ 'singular' => 'slider',
57
+ 'plural' => 'sliders',
58
+ 'ajax' => false
59
+ ));
60
+ }
61
+
62
+ /**
63
+ * Gets the page slug
64
+ *
65
+ * @return string|false
66
+ */
67
+ protected function getPage()
68
+ {
69
+ if ( ! empty($_GET['page'])) {
70
+ return $_GET['page'];
71
+ }
72
+
73
+ return false;
74
+ }
75
+
76
+ /**
77
+ * Show the search field
78
+ *
79
+ * @param string $text Label for the search box
80
+ * @param string $input_id ID of the search box
81
+ * @return void
82
+ */
83
+ public function search_box( $text, $input_id ) {
84
+
85
+ ?>
86
+ <p class="search-box">
87
+ <?php if ( ! empty( $_GET['status'] ) ) : ?>
88
+ <input type="hidden" name="status" value="<?php echo esc_attr( $_GET['status'] ); ?>">
89
+ <?php endif; ?>
90
+ <label class="screen-reader-text" for="<?php echo "{$input_id}-search-input"; ?>"><?php echo $text; ?>:</label>
91
+ <input type="search" id="<?php echo "{$input_id}-search-input"; ?>" name="s" value="<?php _admin_search_query(); ?>" />
92
+ <?php submit_button( $text, 'button', false, false, array( 'ID' => 'search-submit' ) ); ?>
93
+ </p>
94
+ <?php
95
+
96
+ }
97
+
98
+ /**
99
+ * Get our list table views
100
+ *
101
+ * @return array
102
+ */
103
+ public function get_views() {
104
+
105
+ // Get current status
106
+ $current_status = ( isset( $_GET['status'] ) ) ? $_GET['status'] : 'all';
107
+
108
+ // Generate the counts
109
+ $total_count = $this->sliders->total();
110
+ $publish_count = $this->sliders->total( 'publish' );
111
+ $trash_count = $this->sliders->total( 'trash' );
112
+
113
+ // Populate the view links
114
+ $views = array(
115
+ 'all' => sprintf( '<a href="%s"%s>%s</a>', remove_query_arg( 'status' ), ( ! isset( $_GET['s'] ) && 'all' === $current_status || '' === $current_status ) ? ' class="current"' : '', __( 'All', 'easingslider' ) . '&nbsp;<span class="count">('. $total_count .')</span>' ),
116
+ 'publish' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( 'status', 'publish' ), 'publish' === $current_status ? ' class="current"' : '', __( 'Published', 'easingslider' ) . '&nbsp;<span class="count">('. $publish_count .')</span>' ),
117
+ );
118
+
119
+ // Add trashed view only if we have trashed sliders
120
+ if ( $trash_count > 0 ) {
121
+ $views['trash'] = sprintf( '<a href="%s"%s>%s</a>', add_query_arg( 'status', 'trash' ), 'trash' === $current_status ? ' class="current"' : '', __( 'Trashed', 'easingslider' ) . '&nbsp;<span class="count">('. $trash_count .')</span>' );
122
+ }
123
+
124
+ return apply_filters( 'easingslider_sliders_list_table_views', $views );
125
+
126
+ }
127
+
128
+ /**
129
+ * Get our list table columns
130
+ *
131
+ * @return array
132
+ */
133
+ public function get_columns() {
134
+
135
+ // Set our columns
136
+ $columns = array(
137
+ 'cb' => '<input type="checkbox" />',
138
+ 'ID' => __( 'ID', 'easingslider' ),
139
+ 'post_title' => __( 'Title', 'easingslider' ),
140
+ 'post_author' => __( 'Author', 'easingslider' ),
141
+ 'post_date' => __( 'Date', 'easingslider' ),
142
+ 'shortcode' => __( 'Shortcode', 'easingslider' ),
143
+ 'template_function' => __( 'Template Function', 'easingslider' )
144
+ );
145
+
146
+ return apply_filters( 'easingslider_sliders_list_table_columns', $columns );
147
+
148
+ }
149
+
150
+ /**
151
+ * Get the columns that have been hidden by the current user
152
+ *
153
+ * @return array
154
+ */
155
+ public function get_hidden_columns() {
156
+
157
+ // Get the current screen
158
+ $current_screen = get_current_screen();
159
+
160
+ // Get the hidden columns
161
+ $hidden_columns = (array) get_user_option( "manage{$current_screen->id}columnshidden" );
162
+
163
+ return $hidden_columns;
164
+
165
+ }
166
+
167
+ /**
168
+ * Decide which columns to activate the sorting functionality on
169
+ *
170
+ * @return array
171
+ */
172
+ public function get_sortable_columns() {
173
+
174
+ // Set our sortable columns
175
+ $sortable_columns = array(
176
+ 'ID' => array( 'ID', false ),
177
+ 'post_title' => array( 'post_title', false ),
178
+ 'post_author' => array( 'post_author', false ),
179
+ 'post_date' => array( 'post_date', false )
180
+ );
181
+
182
+ return apply_filters( 'easingslider_sliders_list_table_sortable_columns', $sortable_columns );
183
+
184
+ }
185
+
186
+ /**
187
+ * Gets the number of list items per page
188
+ *
189
+ * @return int
190
+ */
191
+ public function get_per_page() {
192
+
193
+ // Get the current page
194
+ $current_screen = get_current_screen();
195
+
196
+ // Get the number of items per page
197
+ $per_page = (int) get_user_option( 'sliders_per_page' );
198
+
199
+ // Return default if false
200
+ if ( ! $per_page ) {
201
+ return 20;
202
+ }
203
+
204
+ return $per_page;
205
+
206
+ }
207
+
208
+ /**
209
+ * Prepare our list table items
210
+ *
211
+ * @return void
212
+ */
213
+ public function prepare_items() {
214
+
215
+ // Process any outstanding bulk actions
216
+ $this->process_bulk_action();
217
+
218
+ // Get our variables
219
+ $columns = $this->get_columns();
220
+ $hidden_columns = $this->get_hidden_columns();
221
+ $sortable_columns = $this->get_sortable_columns();
222
+
223
+ // Get our pagination variables
224
+ $per_page = $this->get_per_page();
225
+ $current_page = $this->get_pagenum();
226
+
227
+ // Our posts query arguments
228
+ $query_args = array(
229
+ 'posts_per_page' => $per_page,
230
+ );
231
+
232
+ // Add post status
233
+ if ( isset( $_GET['status'] ) ) {
234
+ $query_args['post_status'] = sanitize_key( $_GET['status'] );
235
+ }
236
+
237
+ // If paginated, ammend our query
238
+ if ( isset( $_GET['paged'] ) ) {
239
+ $query_args['paged'] = sanitize_key( $_GET['paged'] );
240
+ }
241
+
242
+ // If searching, ammend our query
243
+ if ( isset( $_GET['s'] ) ) {
244
+ $query_args['s'] = sanitize_title( $_GET['s'] );
245
+ }
246
+
247
+ // Add sort queries
248
+ $query_args['orderby'] = ( ! empty( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : 'ID';
249
+ $query_args['order'] = ( ! empty( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : 'asc';
250
+
251
+ // Query our sliders
252
+ $query = $this->sliders->queryPosts( $query_args );
253
+
254
+ // Set our pagination arguments
255
+ $this->set_pagination_args( array(
256
+ 'total_items' => $query->found_posts,
257
+ 'per_page' => $per_page
258
+ ) );
259
+
260
+ // Set our column headers
261
+ $this->_column_headers = array( $columns, $hidden_columns, $sortable_columns );
262
+
263
+ // Assign our table items
264
+ $this->items = $query->posts;
265
+
266
+ }
267
+
268
+ /**
269
+ * Our bulk actions for this list
270
+ *
271
+ * @return array
272
+ */
273
+ public function get_bulk_actions() {
274
+
275
+ $actions = array();
276
+
277
+ // Vary actions based on post status
278
+ if ( isset( $_GET['status'] ) && 'trash' == $_GET['status'] ) {
279
+ $actions['untrash'] = __( 'Restore', 'easingslider' );
280
+ $actions['delete'] = __( 'Delete Permanently', 'easingslider' );
281
+ }
282
+ else {
283
+ $actions['duplicate'] = __( 'Duplicate', 'easingslider' );
284
+ $actions['trash'] = __( 'Move to Trash', 'easingslider' );
285
+ }
286
+
287
+ return apply_filters( 'easingslider_sliders_list_table_bulk_actions', $actions );
288
+
289
+ }
290
+
291
+ /**
292
+ * Processes a bulk action, or a bulk action if appropriate.
293
+ *
294
+ * @return void
295
+ */
296
+ public function process_bulk_action() {
297
+
298
+ // Get the current action
299
+ $action = $this->current_action();
300
+
301
+ // Continue if we have IDs and an action
302
+ if ( $action && isset( $_GET['ids'] ) ) {
303
+
304
+ // Get the IDs
305
+ $ids = array_map( 'sanitize_key', $_GET['ids'] );
306
+
307
+ // Process action in bulk
308
+ foreach ( $ids as $id ) {
309
+ switch ( $action ) {
310
+ case 'duplicate':
311
+ $this->sliders->duplicate( $id );
312
+ break;
313
+
314
+ case 'trash':
315
+ $this->sliders->trash( $id );
316
+ break;
317
+
318
+ case 'untrash':
319
+ $this->sliders->untrash( $id );
320
+ break;
321
+
322
+ case 'delete':
323
+ $this->sliders->delete( $id );
324
+ break;
325
+ }
326
+ }
327
+
328
+ }
329
+
330
+ /*
331
+ // Continue if callback exists
332
+ if ( function_exists( $callback ) ) {
333
+
334
+ // Do either a single action or a bulk action
335
+ if ( isset( $_GET['id'] ) ) {
336
+
337
+ // Bail if nonce is invalid
338
+ if ( ! check_admin_referer( $action ) ) {
339
+ return;
340
+ }
341
+
342
+ // Call the action
343
+ call_user_func( $callback, sanitize_key( $_GET['id'] ) );
344
+
345
+ }
346
+ elseif ( isset( $_GET['ids'] ) ) {
347
+
348
+ // Bail if nonce is invalid
349
+ if ( ! check_admin_referer( "bulk-{$this->_args['plural']}" ) ) {
350
+ return;
351
+ }
352
+
353
+ // Sanatize IDs
354
+ $ids = array_map( 'sanitize_key', $_GET['ids'] );
355
+
356
+ // Call the action for each ID
357
+ array_walk( $ids, $callback );
358
+
359
+ }
360
+
361
+ }
362
+ */
363
+
364
+ }
365
+
366
+ /**
367
+ * Our checkbox column method
368
+ *
369
+ * @param object $item Our column item
370
+ * @return string
371
+ */
372
+ public function column_cb( $item ) {
373
+
374
+ return sprintf( '<input type="checkbox" name="ids[]" value="%s" />', $item->ID );
375
+
376
+ }
377
+
378
+ /**
379
+ * Our post title column method
380
+ *
381
+ * @param object $item Our column item
382
+ * @return string
383
+ */
384
+ public function column_post_title( $item ) {
385
+
386
+ $actions = array();
387
+
388
+ // Vary actions based on post status
389
+ if ( isset( $_GET['status'] ) && 'trash' === $_GET['status'] ) {
390
+
391
+ // Title string
392
+ $title = sprintf( '<strong>%s</strong>', $item->post_title );
393
+
394
+ // Add nonces to action URLs
395
+ $untrash_link = wp_nonce_url( "?page={$this->page}&easingslider_action=untrash_slider&id={$item->ID}&easingslider_notice=untrash_slider", 'untrash' );
396
+ $delete_link = wp_nonce_url( "?page={$this->page}&easingslider_action=delete_slider&id={$item->ID}&easingslider_notice=delete_slider", 'delete' );
397
+
398
+ // Add our actions
399
+ $actions['untrash'] = sprintf( '<a href="%s">Restore</a>', $untrash_link );
400
+ $actions['delete'] = sprintf( '<a href="%s">Delete Permanently</a>', $delete_link );
401
+
402
+ }
403
+ else {
404
+
405
+ // Title string
406
+ $title = sprintf( '<strong><a class="row-title" href="?page=%s&edit=%s">%s</a></strong>', $this->page, $item->ID, $item->post_title );
407
+
408
+ // Add nonces to action URLs
409
+ $duplicate_link = wp_nonce_url( "?page={$this->page}&easingslider_action=duplicate_slider&id={$item->ID}&easingslider_notice=duplicate_slider", 'duplicate' );
410
+ $trash_link = wp_nonce_url( "?page={$this->page}&easingslider_action=trash_slider&id={$item->ID}&easingslider_notice=trash_slider", 'trash' );
411
+
412
+ // Add our actions
413
+ $actions['edit'] = sprintf( '<a href="?page=%s&edit=%s">Edit</a>', $this->page, $item->ID );
414
+ $actions['duplicate'] = sprintf( '<a href="%s">Duplicate</a>', $duplicate_link );
415
+ $actions['trash'] = sprintf( '<a href="%s">Trash</a>', $trash_link );
416
+
417
+ }
418
+
419
+ // Filter the actions
420
+ $actions = apply_filters( 'easingslider_sliders_list_table_post_title_actions', $actions );
421
+
422
+ return sprintf( '%1$s %2$s', $title, $this->row_actions( $actions ) );
423
+
424
+ }
425
+
426
+ /**
427
+ * Our post author column method
428
+ *
429
+ * @param object $item Our column item
430
+ * @return string
431
+ */
432
+ public function column_post_author( $item ) {
433
+
434
+ $author = sprintf(
435
+ '<a href="%s">%s</a>',
436
+ esc_url( add_query_arg( array( 'page' => $this->page, 'author' => get_the_author_meta( 'ID', $item->post_author ) ) ) ),
437
+ get_the_author_meta( 'display_name', $item->post_author )
438
+ );
439
+
440
+ return sprintf( '%1$s', $author );
441
+
442
+ }
443
+
444
+ /**
445
+ * Our post date column method
446
+ *
447
+ * @param object $item Our column item
448
+ * @return string
449
+ */
450
+ public function column_post_date( $item ) {
451
+
452
+ // Get the time strings
453
+ $post_time = get_post_time( 'G', true, $item->ID );
454
+ $abbr_time = get_post_time( 'Y/m/d g:i:s A', true, $item->ID );
455
+
456
+ // Calculate the time difference from now
457
+ $time_diff = time() - $post_time;
458
+
459
+ // Get the appropriate time string
460
+ if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
461
+
462
+ // Return a pretty text string
463
+ $date = sprintf( __( '%s ago', 'easingslider' ), human_time_diff( $post_time ) );
464
+
465
+ }
466
+ else {
467
+
468
+ // Return a date, month and year string
469
+ $date = mysql2date( __( 'Y/m/d' ), $item->post_date );
470
+
471
+ }
472
+
473
+ return sprintf( '%1$s<br><abbr title="%2$s">%3$s</abbr>', __( 'Published', 'easingslider' ), $abbr_time, $date );
474
+
475
+ }
476
+
477
+ /**
478
+ * Our shortcode column method
479
+ *
480
+ * @param object $item Our column item
481
+ * @return string
482
+ */
483
+ public function column_shortcode( $item ) {
484
+
485
+ $shortcode = sprintf( esc_html( "[{$this->shortcode->tag()} id=\"%d\"]" ), $item->ID );
486
+
487
+ return sprintf( '<input type="text" readonly="readonly" value="%s" />', $shortcode );
488
+
489
+ }
490
+
491
+ /**
492
+ * Our template function column method
493
+ *
494
+ * @param object $item Our column item
495
+ * @return string
496
+ */
497
+ public function column_template_function( $item ) {
498
+
499
+ $template_function = sprintf( esc_html( '<?php if ( function_exists( \'easingslider\' ) ) { easingslider( %d ); } ?>' ), $item->ID );
500
+
501
+ return sprintf( '<input type="text" readonly="readonly" value="%s" />', $template_function );
502
+
503
+ }
504
+
505
+ /**
506
+ * Our default column methods
507
+ *
508
+ * @param array $item Our column item
509
+ * @param string $column_name The column name
510
+ * @return string
511
+ */
512
+ public function column_default( $item, $column_name ) {
513
+
514
+ switch ( $column_name ) {
515
+ default:
516
+ return $item->$column_name;
517
+ }
518
+
519
+ }
520
+
521
+ /**
522
+ * Our custom "No items" text
523
+ *
524
+ * @return void
525
+ */
526
+ public function no_items() {
527
+
528
+ // That's all folks!
529
+ _e( 'No sliders found.', 'easingslider' );
530
+
531
+ }
532
+
533
+ }
src/Plugin/Admin/MediaButton.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin;
4
+
5
+ use EasingSlider\Foundation\Contracts\Shortcodes\Shortcode;
6
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class MediaButton
16
+ {
17
+ /**
18
+ * Shortcode
19
+ *
20
+ * @var \EasingSlider\Plugin\Contracts\Shortcodes\Shortcode
21
+ */
22
+ protected $shortcode;
23
+
24
+ /**
25
+ * Slides
26
+ *
27
+ * @var \EasingSlider\Plugin\Contracts\Repositories\Repository
28
+ */
29
+ protected $sliders;
30
+
31
+ /**
32
+ * Constructor
33
+ *
34
+ * @param \EasingSlider\Plugin\Contracts\Shortcodes\Shortcode $sliders
35
+ * @param \EasingSlider\Plugnin\Contracts\Repositories\Repository $shortcode
36
+ * @return void
37
+ */
38
+ public function __construct(Repository $sliders, Shortcode $shortcode)
39
+ {
40
+ $this->sliders = $sliders;
41
+ $this->shortcode = $shortcode;
42
+
43
+ $this->defineHooks();
44
+ }
45
+
46
+ /**
47
+ * Define hooks
48
+ *
49
+ * @return void
50
+ */
51
+ public function defineHooks()
52
+ {
53
+ add_action('media_buttons', array($this, 'displayButton'));
54
+ }
55
+
56
+ /**
57
+ * Displays the media button
58
+ *
59
+ * @return void
60
+ */
61
+ public function displayButton()
62
+ {
63
+ // Print the button's HTML and CSS
64
+ ?>
65
+ <style type="text/css">
66
+ .wp-media-buttons .insert-slider span.wp-media-buttons-icon {
67
+ margin-top: -2px;
68
+ }
69
+ .wp-media-buttons .insert-slider span.wp-media-buttons-icon:before {
70
+ content: "\f232";
71
+ font: 400 18px/1 dashicons;
72
+ speak: none;
73
+ -webkit-font-smoothing: antialiased;
74
+ -moz-osx-font-smoothing: grayscale;
75
+ }
76
+ </style>
77
+
78
+ <a href="#TB_inline?width=480&amp;inlineId=select-slider" class="button thickbox insert-slider" data-editor="<?php echo esc_attr($editor_id); ?>" title="<?php _e('Add a Slider', 'easingslider'); ?>">
79
+ <span class="wp-media-buttons-icon dashicons dashicons-format-image"></span><?php _e(' Add Slider', 'easingslider'); ?>
80
+ </a>
81
+ <?php
82
+
83
+ // Enqueue the thickbox (required for button to work)
84
+ add_action('admin_footer', array($this, 'printThickbox'));
85
+ }
86
+
87
+ /**
88
+ * Prints the thickbox for our media button
89
+ *
90
+ * @return void
91
+ */
92
+ public function printThickbox()
93
+ {
94
+ ?>
95
+ <style type="text/css">
96
+ #TB_window .section {
97
+ padding: 15px 15px 0 15px;
98
+ }
99
+ </style>
100
+
101
+ <script type="text/javascript">
102
+ /**
103
+ * Sends a shortcode to the post/page editor
104
+ */
105
+ function insertSlider() {
106
+
107
+ // Get the slider ID
108
+ var id = jQuery('#slider').val();
109
+
110
+ // Display alert and bail if no slideshow was selected
111
+ if ('-1' === id) {
112
+ return alert("<?php _e('Please select a slider', 'easingslider'); ?>");
113
+ }
114
+
115
+ // Send shortcode to editor
116
+ send_to_editor('[<?php echo esc_attr($this->shortcode->tag()); ?> id=\"'+ id +'\"]');
117
+
118
+ // Close thickbox
119
+ tb_remove();
120
+
121
+ }
122
+ </script>
123
+
124
+ <div id="select-slider" style="display: none;">
125
+ <div class="section">
126
+ <h2><?php _e('Add a slider', 'easingslider'); ?></h2>
127
+ <span><?php _e('Select a slider to insert from the box below.', 'easingslider'); ?></span>
128
+ </div>
129
+
130
+ <div class="section">
131
+ <select name="slider" id="slider">
132
+ <option value="-1"><?php _e('Select a slider', 'easingslider'); ?></option>
133
+ <?php foreach ($this->sliders->all() as $slider) : ?>
134
+ <option value="<?php echo esc_attr($slider->ID); ?>"><?php echo esc_html(sprintf("%s (ID #%d)", $slider->post_title, $slider->ID)); ?></option>
135
+ <?php endforeach; ?>
136
+ </select>
137
+ </div>
138
+
139
+ <div class="section">
140
+ <button id="insert-slider" class="button-primary" onClick="insertSlider();"><?php _e('Insert Slider', 'easingslider'); ?></button>
141
+ <button id="close-slider-thickbox" class="button-secondary" style="margin-left: 5px;" onClick="tb_remove();"><?php _e('Close', 'easingslider'); ?></a>
142
+ </div>
143
+ </div>
144
+ <?php
145
+ }
146
+ }
src/Plugin/Admin/Menus/Menu.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Menus;
4
+
5
+ use EasingSlider\Foundation\Admin\Menus\Menu as BaseMenu;
6
+ use EasingSlider\Foundation\Contracts\Admin\Panels\Panels;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class Menu extends BaseMenu
16
+ {
17
+ /**
18
+ * Panels
19
+ *
20
+ * @var \EasingSlider\Foundation\Contracts\Admin\Panels\Panels
21
+ */
22
+ protected $panels;
23
+
24
+ /**
25
+ * Constructor
26
+ *
27
+ * @param \EasingSlider\Foundation\Contracts\Admin\Panels\Panels $panels
28
+ * @return void
29
+ */
30
+ public function __construct(Panels $panels)
31
+ {
32
+ $this->panels = $panels;
33
+
34
+ parent::__construct();
35
+ }
36
+
37
+ /**
38
+ * Setup menu
39
+ *
40
+ * @return void
41
+ */
42
+ public function setupMenu()
43
+ {
44
+ $this->setupTopLevelMenu();
45
+ $this->setupAllSlidersPanel();
46
+ $this->setupAddNewPanel();
47
+ $this->setupSettingsPanel();
48
+ $this->setupAddonsPanel();
49
+ }
50
+
51
+ /**
52
+ * Sets up the toplevel page for this menu
53
+ *
54
+ * @return void
55
+ */
56
+ protected function setupToplevelMenu()
57
+ {
58
+ $this->setToplevelMenu(
59
+ __('Sliders', 'easingslider'),
60
+ __('Sliders', 'easingslider'),
61
+ 'easingslider_edit_sliders',
62
+ 'easingslider',
63
+ null,
64
+ 'dashicons-images-alt'
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Sets up the "All Sliders" page
70
+ *
71
+ * @return void
72
+ */
73
+ protected function setupAllSlidersPanel()
74
+ {
75
+ $this->addSubmenuPage(
76
+ __('Sliders', 'easingslider'),
77
+ __('All Sliders', 'easingslider'),
78
+ 'easingslider_edit_sliders',
79
+ 'easingslider',
80
+ array($this->panels['all_sliders'], 'display')
81
+ );
82
+ }
83
+
84
+ /**
85
+ * Sets up the "Add New" page
86
+ *
87
+ * @return void
88
+ */
89
+ protected function setupAddNewPanel()
90
+ {
91
+ $this->addSubmenuPage(
92
+ __('Add New Slider', 'easingslider'),
93
+ __('Add New', 'easingslider'),
94
+ 'easingslider_publish_sliders',
95
+ 'easingslider-add-new',
96
+ array($this->panels['create_slider'], 'display')
97
+ );
98
+ }
99
+
100
+ /**
101
+ * Sets up the "Settings" page
102
+ *
103
+ * @return void
104
+ */
105
+ protected function setupSettingsPanel()
106
+ {
107
+ $this->addSubmenuPage(
108
+ __('Settings', 'easingslider'),
109
+ __('Settings', 'easingslider'),
110
+ 'easingslider_manage_settings',
111
+ 'easingslider-settings',
112
+ array($this->panels['settings'], 'display')
113
+ );
114
+ }
115
+
116
+ /**
117
+ * Sets up the "Addons" page
118
+ *
119
+ * @return void
120
+ */
121
+ protected function setupAddonsPanel()
122
+ {
123
+ $this->addSubmenuPage(
124
+ __('Addons', 'easingslider'),
125
+ __('Get More Features!', 'easingslider'),
126
+ 'easingslider_manage_addons',
127
+ 'easingslider-addons',
128
+ array($this->panels['addons'], 'display')
129
+ );
130
+ }
131
+ }
src/Plugin/Admin/Panels/Addons.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Admin\Panels\Panel;
6
+ use EasingSlider\Plugin\Contracts\Options\License;
7
+ use EasingSlider\Plugin\Slider;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ // Uncomment for testing
17
+ // delete_site_transient('easingslider_addons');
18
+
19
+ class Addons extends Panel
20
+ {
21
+ /**
22
+ * License
23
+ *
24
+ * @var \EasingSlider\Plugin\Contracts\Options\License
25
+ */
26
+ protected $license;
27
+
28
+ /**
29
+ * Constructor
30
+ *
31
+ * @param \EasingSlider\Plugin\Contracts\Options\License $license
32
+ * @return void
33
+ */
34
+ public function __construct(License $license)
35
+ {
36
+ $this->license = $license;
37
+ }
38
+
39
+ /**
40
+ * Gets the available addons
41
+ *
42
+ * @return array|false
43
+ */
44
+ protected function getAddons()
45
+ {
46
+ $addons = get_site_transient('easingslider_addons');
47
+
48
+ if (false === $addons) {
49
+
50
+ // Get the request parameters
51
+ $requestParams = array(
52
+ 'easingslider_action' => 'get_addons',
53
+ 'name' => EASINGSLIDER_NAME,
54
+ 'license' => $this->license['key'],
55
+ 'url' => home_url()
56
+ );
57
+
58
+ // Get the addons from API
59
+ $response = wp_remote_post(
60
+ $this->getApiUrl(),
61
+ array(
62
+ 'timeout' => 15,
63
+ 'sslverify' => false,
64
+ 'body' => $requestParams
65
+ )
66
+ );
67
+
68
+ // Check for errors in response
69
+ if (is_wp_error($response)) {
70
+ return false;
71
+ }
72
+
73
+ // Get addons from the response body
74
+ $addons = json_decode(wp_remote_retrieve_body($response));
75
+
76
+ // Check for errors in body
77
+ if (is_wp_error($addons)) {
78
+ return false;
79
+ }
80
+
81
+ // Cache for use later
82
+ set_site_transient('easingslider_addons', $addons, 3600);
83
+
84
+ }
85
+
86
+ return $addons;
87
+ }
88
+
89
+ /**
90
+ * Gets the API URL
91
+ *
92
+ * @return string
93
+ */
94
+ protected function getApiUrl()
95
+ {
96
+ return easingslider_api_url();
97
+ }
98
+
99
+ /**
100
+ * Displays the panel
101
+ *
102
+ * @return void
103
+ */
104
+ public function display()
105
+ {
106
+ $this->showView('view-addons', array(
107
+ 'addons' => $this->getAddons(),
108
+ 'addonsLink' => 'http://easingslider.com/addons',
109
+ 'installedPlugins' => get_plugins(),
110
+ 'license' => $this->license,
111
+ 'page' => $this->getPage(),
112
+ 'purchaseLink' => 'http://easingslider.com/purchase'
113
+ ));
114
+ }
115
+ }
src/Plugin/Admin/Panels/AllSliders.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Admin\Panels\Panel;
6
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
7
+ use EasingSlider\Foundation\Contracts\Shortcodes\Shortcode;
8
+ use EasingSlider\Plugin\Admin\Panels\EditSlider as EditSliderPanel;
9
+ use EasingSlider\Plugin\Admin\Panels\ListSliders as ListSlidersPanel;
10
+
11
+ /**
12
+ * Exit if accessed directly
13
+ */
14
+ if ( ! defined('ABSPATH')) {
15
+ exit;
16
+ }
17
+
18
+ class AllSliders extends Panel
19
+ {
20
+ /**
21
+ * Shortcode
22
+ *
23
+ * @var \EasingSlider\Foundation\Contracts\Shortcodes\Shortcode
24
+ */
25
+ protected $shortcode;
26
+
27
+ /**
28
+ * List table
29
+ *
30
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
31
+ */
32
+ protected $sliders;
33
+
34
+ /**
35
+ * Constructor
36
+ *
37
+ * @param \EasingSlider\Foundation\Contracts\Repositories\Repository $sliders
38
+ * @param \EasingSlider\Foundation\Contracts\Shortcodes\Shortcode $shortcode
39
+ * @return void
40
+ */
41
+ public function __construct(Repository $sliders, Shortcode $shortcode)
42
+ {
43
+ $this->sliders = $sliders;
44
+ $this->shortcode = $shortcode;
45
+ }
46
+
47
+ /**
48
+ * Gets the appropriate page
49
+ *
50
+ * @return \EasingSlider\Panels\PanelContract
51
+ */
52
+ protected function determinePanel()
53
+ {
54
+ $id = $this->getID();
55
+
56
+ // Determine the appropriate
57
+ if ($id) {
58
+ return new EditSliderPanel(
59
+ $this->sliders
60
+ );
61
+ } else {
62
+ return new ListSlidersPanel(
63
+ $this->sliders,
64
+ $this->shortcode
65
+ );
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Displays the panel
71
+ *
72
+ * @return void
73
+ */
74
+ public function display()
75
+ {
76
+ $panel = $this->determinePanel();
77
+
78
+ return $panel->display();
79
+ }
80
+ }
src/Plugin/Admin/Panels/CreateSlider.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
6
+ use EasingSlider\Plugin\Admin\Panels\EditSlider;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class CreateSlider extends EditSlider
16
+ {
17
+ /**
18
+ * Gets the slider
19
+ *
20
+ * @return \EasingSlider\Foundation\Contracts\Models\Model
21
+ */
22
+ protected function getSlider()
23
+ {
24
+ return $this->sliders->make();
25
+ }
26
+ }
src/Plugin/Admin/Panels/EditSlider.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Admin\Panels\Panel;
6
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class EditSlider extends Panel
16
+ {
17
+ /**
18
+ * Slider
19
+ *
20
+ * @var \EasingSlider\Foundation\Contracts\Models\Model
21
+ */
22
+ protected $slider;
23
+
24
+ /**
25
+ * Sliders
26
+ *
27
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
28
+ */
29
+ protected $sliders;
30
+
31
+ /**
32
+ * Constructor
33
+ *
34
+ * @param \EasingSlider\Foundation\Contracts\Repositories\Repository $sliders
35
+ * @return void
36
+ */
37
+ public function __construct(Repository $sliders)
38
+ {
39
+ $this->sliders = $sliders;
40
+
41
+ $this->slider = $this->getSlider();
42
+ }
43
+
44
+ /**
45
+ * Get the slider
46
+ *
47
+ * @return \EasingSlider\Foundation\Contracts\Models\Model
48
+ */
49
+ protected function getSlider()
50
+ {
51
+ return $this->sliders->find($this->getID());
52
+ }
53
+
54
+ /**
55
+ * Gets the possible transitions for a slider
56
+ *
57
+ * @return array
58
+ */
59
+ protected function getTransitions()
60
+ {
61
+ return apply_filters('easingslider_admin_slider_transitions', array(
62
+ 'slide' => __('Slide', 'easingslider'),
63
+ 'fade' => __('Fade', 'easingslider')
64
+ ));
65
+ }
66
+
67
+ /**
68
+ * Gets the possible content types for a slider
69
+ *
70
+ * @return array
71
+ */
72
+ protected function getTypes()
73
+ {
74
+ return apply_filters('easingslider_admin_slider_types', array(
75
+ 'media' => __('Media', 'easingslider')
76
+ ));
77
+ }
78
+
79
+ /**
80
+ * Displays the panel
81
+ *
82
+ * @return void
83
+ */
84
+ public function display()
85
+ {
86
+ $this->showView('edit-slider', array(
87
+ 'page' => $this->getPage(),
88
+ 'slider' => $this->slider,
89
+ 'types' => $this->getTypes(),
90
+ 'transitions' => $this->getTransitions()
91
+ ));
92
+ }
93
+ }
src/Plugin/Admin/Panels/ListSliders.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Admin\Panels\Panel;
6
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
7
+ use EasingSlider\Foundation\Contracts\Shortcodes\Shortcode;
8
+ use EasingSlider\Plugin\Admin\ListTables\Sliders as SlidersListTable;
9
+
10
+ /**
11
+ * Exit if accessed directly
12
+ */
13
+ if ( ! defined('ABSPATH')) {
14
+ exit;
15
+ }
16
+
17
+ class ListSliders extends Panel
18
+ {
19
+ /**
20
+ * Shortcode
21
+ *
22
+ * @var \EasingSlider\Foundation\Contracts\Shortcodes\Shortcode
23
+ */
24
+ protected $shortcode;
25
+
26
+ /**
27
+ * Sliders
28
+ *
29
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
30
+ */
31
+ protected $sliders;
32
+
33
+ /**
34
+ * Constructor
35
+ *
36
+ * @param \EasingSlider\Foundation\Contracts\Repositories\Repository $sliders
37
+ * @param \EasingSlider\Foundation\Contracts\Shortcodes\Shortcode $shortcode
38
+ * @return void
39
+ */
40
+ public function __construct(Repository $sliders, Shortcode $shortcode)
41
+ {
42
+ $this->sliders = $sliders;
43
+ $this->shortcode = $shortcode;
44
+ }
45
+
46
+ /**
47
+ * Gets the page slug
48
+ *
49
+ * @return string|false
50
+ */
51
+ protected function getPage()
52
+ {
53
+ if ( ! empty($_GET['page'])) {
54
+ return $_GET['page'];
55
+ }
56
+
57
+ return false;
58
+ }
59
+
60
+ /**
61
+ * Displays the panel
62
+ *
63
+ * @return void
64
+ */
65
+ public function display()
66
+ {
67
+ $listTable = new SlidersListTable(
68
+ $this->sliders,
69
+ $this->shortcode
70
+ );
71
+
72
+ $this->showView('list-sliders', array(
73
+ 'listTable' => $listTable,
74
+ 'page' => $this->getPage()
75
+ ));
76
+ }
77
+ }
src/Plugin/Admin/Panels/Panels.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Admin\Panels\Panels as BasePanels;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class Panels extends BasePanels
15
+ {
16
+ /**
17
+ * Boot
18
+ *
19
+ * @return void
20
+ */
21
+ protected function boot()
22
+ {
23
+ $this->panels['addons'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Panels\Addons');
24
+ $this->panels['all_sliders'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Panels\AllSliders');
25
+ $this->panels['create_slider'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Panels\CreateSlider');
26
+ $this->panels['edit_slider'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Panels\EditSlider');
27
+ $this->panels['list_sliders'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Panels\ListSliders');
28
+ $this->panels['settings'] = $this->plugin->make('\EasingSlider\Plugin\Admin\Panels\Settings');
29
+ }
30
+
31
+ /**
32
+ * Gets our custom admin footer text
33
+ *
34
+ * @return string
35
+ */
36
+ public function getFooterText()
37
+ {
38
+ return sprintf(
39
+ __('Please rate <strong>Easing Slider</strong> <a href="%1$s" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href="%1$s" target="_blank">WordPress.org</a> to help us keep this plugin free. Thank you from the Easing Slider team!', 'easingslider'),
40
+ __('http://wordpress.org/support/view/plugin-reviews/easing-slider?filter=5', 'easingslider')
41
+ );
42
+ }
43
+ }
src/Plugin/Admin/Panels/Settings.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Panels;
4
+
5
+ use EasingSlider\Foundation\Admin\Panels\SettingsApiPanel;
6
+ use EasingSlider\Plugin\Admin\Validators\Settings as SettingsValidator;
7
+ use EasingSlider\Plugin\Contracts\Options\Settings as SettingsOption;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ class Settings extends SettingsApiPanel
17
+ {
18
+ /**
19
+ * Constructor
20
+ *
21
+ * @param \EasingSlider\Plugin\Contracts\Options\Settings $settings
22
+ * @return void
23
+ */
24
+ public function __construct(SettingsOption $settings)
25
+ {
26
+ parent::__construct($settings);
27
+ }
28
+
29
+ /**
30
+ * Gets the tabs
31
+ *
32
+ * @return array
33
+ */
34
+ protected function getTabs()
35
+ {
36
+ return apply_filters('easingslider_settings_tabs', array(
37
+ 'general' => __('General', 'easingslider'),
38
+ 'diagnostics' => __('Diagnostics', 'easingslider')
39
+ ));
40
+ }
41
+
42
+ /**
43
+ * Gets the sections
44
+ *
45
+ * @return array
46
+ */
47
+ protected function getSections()
48
+ {
49
+ global $wpdb, $wp_version;
50
+
51
+ $sections = array(
52
+ 'general' => apply_filters('easingslider_settings_general', array(
53
+ 'assets_header' => array(
54
+ 'name' => __('Asset Loading', 'easingslider'),
55
+ 'type' => 'header'
56
+ ),
57
+ 'load_in_footer' => array(
58
+ 'name' => __('Load in Footer', 'easingslider'),
59
+ 'type' => 'checkbox',
60
+ 'desc' => __('Should Easing Slider load it\'s CSS & Javascript in the page footer? This reduces page loading time, but may be prone to conflicts with other plugins.', 'easingslider'),
61
+ 'std' => false
62
+ ),
63
+ 'data_header' => array(
64
+ 'name' => __('Data Settings', 'easingslider'),
65
+ 'type' => 'header'
66
+ ),
67
+ 'remove_data' => array(
68
+ 'name' => __('Remove data on uninstall?', 'easingslider'),
69
+ 'type' => 'checkbox',
70
+ 'desc' => __('Check this box if you would like Easing Slider to completely remove all of its data when the plugin is deleted.', 'easingslider'),
71
+ 'std' => false
72
+ ),
73
+ 'reset_plugin' => array(
74
+ 'name' => __('Reset data to defaults', 'easingslider'),
75
+ 'type' => 'action',
76
+ 'action' => 'reset_plugin',
77
+ 'label' => __('Reset Plugin', 'easingslider'),
78
+ 'desc' => __('Click this button to completely reset your Easing Slider settings back to defaults. Be careful, as this process cannot be reversed!', 'easingslider'),
79
+ ),
80
+ )),
81
+ 'diagnostics' => apply_filters('easingslider_settings_diagnostics', array(
82
+ 'installation_header' => array(
83
+ 'name' => __('System Settings', 'easingslider'),
84
+ 'type' => 'header'
85
+ ),
86
+ 'php_version' => array(
87
+ 'name' => __('PHP Version', 'easingslider'),
88
+ 'type' => 'info',
89
+ 'std' => phpversion()
90
+ ),
91
+ 'mysql_version' => array(
92
+ 'name' => __('MySQL Version', 'easingslider'),
93
+ 'type' => 'info',
94
+ 'std' => $wpdb->get_var('SELECT VERSION()')
95
+ ),
96
+ 'wordpress_version' => array(
97
+ 'name' => __('WordPress Version', 'easingslider'),
98
+ 'type' => 'info',
99
+ 'std' => $wp_version
100
+ ),
101
+ 'easingslider_version' => array(
102
+ 'name' => __('Plugin Version', 'easingslider'),
103
+ 'type' => 'info',
104
+ 'std' => EASINGSLIDER_VERSION
105
+ ),
106
+ ))
107
+ );
108
+
109
+ return apply_filters('easingslider_settings_sections', $sections);
110
+ }
111
+
112
+ /**
113
+ * Gets a new validator instance
114
+ *
115
+ * @return array
116
+ */
117
+ protected function validator()
118
+ {
119
+ return new SettingsValidator();
120
+ }
121
+
122
+ /**
123
+ * Displays the panel
124
+ *
125
+ * @return void
126
+ */
127
+ public function display()
128
+ {
129
+ $this->showView('edit-settings', array(
130
+ 'activeTab' => $this->getActiveTab(),
131
+ 'optionName' => $this->option->getName(),
132
+ 'sections' => $this->getSections(),
133
+ 'tabs' => $this->getTabs()
134
+ ));
135
+ }
136
+ }
src/Plugin/Admin/UpgraderSkin.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin;
4
+
5
+ use WP_Upgrader_Skin;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class UpgraderSkin extends WP_Upgrader_Skin
15
+ {
16
+ /**
17
+ * Primary class constructor.
18
+ *
19
+ * @param array $args Empty array of args (we will use defaults).
20
+ * @return void
21
+ */
22
+ public function __construct($args = array())
23
+ {
24
+ parent::__construct();
25
+ }
26
+
27
+ /**
28
+ * Set the upgrader object and store it as a property in the parent class.
29
+ *
30
+ * @param object $upgrader The upgrader object (passed by reference).
31
+ * @return void
32
+ */
33
+ public function set_upgrader(&$upgrader)
34
+ {
35
+ if (is_object($upgrader)) {
36
+ $this->upgrader =& $upgrader;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Set the upgrader result and store it as a property in the parent class.
42
+ *
43
+ * @param object $result The result of the install process.
44
+ * @return void
45
+ */
46
+ public function set_result($result)
47
+ {
48
+ $this->result = $result;
49
+ }
50
+
51
+ /**
52
+ * Empty out the header of its HTML content and only check to see if it has
53
+ * been performed or not.
54
+ *
55
+ * @return void
56
+ */
57
+ public function header()
58
+ {
59
+ //
60
+ }
61
+
62
+ /**
63
+ * Empty out the footer of its HTML contents.
64
+ *
65
+ * @return void
66
+ */
67
+ public function footer()
68
+ {
69
+ //
70
+ }
71
+
72
+ /**
73
+ * Instead of outputting HTML for errors, json_encode the errors and send them
74
+ * back to the Ajax script for processing.
75
+ *
76
+ * @param array $errors Array of errors with the install process.
77
+ * @return void
78
+ */
79
+ public function error($errors)
80
+ {
81
+ if ( ! empty($errors)) {
82
+ echo json_encode(
83
+ array(
84
+ 'errors' => $errors,
85
+ 'message' => __('There was an error installing the addon. Please try again.', 'easingslider')
86
+ )
87
+ );
88
+ die;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Empty out the feedback method to prevent outputting HTML strings as the install
94
+ * is progressing.
95
+ *
96
+ * @param string $string The feedback string.
97
+ * @return void
98
+ */
99
+ public function feedback($string)
100
+ {
101
+ //
102
+ }
103
+ }
src/Plugin/Admin/Upgrades/UpgradeTo300.php ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Upgrades;
4
+
5
+ use WP_Roles;
6
+ use WP_Query;
7
+ use EasingSlider\Plugin\Admin\Upgrades\Upgrader;
8
+ use EasingSlider\Plugin\Contracts\Options\License;
9
+ use EasingSlider\Plugin\Contracts\Options\Settings;
10
+ use EasingSlider\Plugin\Contracts\Options\Version;
11
+
12
+ /**
13
+ * Exit if accessed directly
14
+ */
15
+ if ( ! defined('ABSPATH')) {
16
+ exit;
17
+ }
18
+
19
+ class UpgradeTo300 extends Upgrader
20
+ {
21
+ /**
22
+ * Settings
23
+ *
24
+ * @var \EasingSlider\Plugin\Contracts\Options\Settings
25
+ */
26
+ protected $settings;
27
+
28
+ /**
29
+ * License
30
+ *
31
+ * @var \EasingSlider\Plugin\Contracts\Options\License
32
+ */
33
+ protected $license;
34
+
35
+ /**
36
+ * The version we're upgrading from (or greater)
37
+ *
38
+ * @var string
39
+ */
40
+ protected $upgradeFrom = '2.2';
41
+
42
+ /**
43
+ * The version we're upgrading too
44
+ *
45
+ * @var string
46
+ */
47
+ protected $upgradeTo = '3.0.0';
48
+
49
+ /**
50
+ * Operator for version comparison
51
+ *
52
+ * @var string
53
+ */
54
+ protected $operator = '>=';
55
+
56
+ /**
57
+ * Constructor
58
+ *
59
+ * @param \EasingSlider\Plugin\Contracts\Options\Version $version
60
+ * @param \EasingSlider\Plugin\Contracts\Options\Settings $settings
61
+ * @param \EasingSlider\Plugin\Contracts\Options\License $license
62
+ * @return void
63
+ */
64
+ public function __construct(Version $version, Settings $settings, License $license)
65
+ {
66
+ $this->settings = $settings;
67
+ $this->license = $license;
68
+
69
+ parent::__construct($version);
70
+ }
71
+
72
+ /**
73
+ * Sets an option telling us that this user has upgraded from a previous version to v3.0.0.
74
+ * This allows us to conditionally display an notice providing information related to the upgrade.
75
+ *
76
+ * @return void
77
+ */
78
+ protected function setupUpgradeNotice()
79
+ {
80
+ add_option('easingslider_upgraded_from_v2', true);
81
+ }
82
+
83
+ /**
84
+ * Migrates the license key
85
+ *
86
+ * @return void
87
+ */
88
+ protected function migrateLicense()
89
+ {
90
+ // Set the license key
91
+ $this->license['key'] = get_option('easingslider_license_key');
92
+
93
+ // Save it
94
+ $this->license->save();
95
+
96
+ // Delete old license key
97
+ delete_option('easingslider_license_key');
98
+ }
99
+
100
+ /**
101
+ * Upgrades the plugin settings
102
+ *
103
+ * @return void
104
+ */
105
+ protected function upgradeSettings()
106
+ {
107
+ // Get new settings array of defaults
108
+ $settings = $this->settings->getDefaults();
109
+
110
+ // Get the old settings
111
+ $oldSettings = (array) get_option('easingslider_settings');
112
+
113
+ // Convert "Load in Footer" option
114
+ if (isset($oldSettings['load_assets']) && 'footer' == $oldSettings['load_assets']) {
115
+ $settings['load_in_footer'] = true;
116
+ }
117
+
118
+ // Convert "Remove Data" option
119
+ $settings['remove_data'] = $oldSettings['remove_data'];
120
+
121
+ // Set the new settings
122
+ $this->settings->value = $settings;
123
+
124
+ // Update the settings
125
+ $this->settings->save();
126
+ }
127
+
128
+ /**
129
+ * Upgrades the plugin capaiblities
130
+ *
131
+ * @return void
132
+ */
133
+ protected function upgradeCapabilities()
134
+ {
135
+ global $wp_roles;
136
+
137
+ // Check for roles
138
+ if (class_exists('WP_Roles')) {
139
+ if ( ! isset($wp_roles)) {
140
+ $wp_roles = new WP_Roles();
141
+ }
142
+ }
143
+
144
+ /**
145
+ * In this version (v2.3), we've also unprefixed the plugin capabilities.
146
+ * Let's reflect this.
147
+ */
148
+ if (is_object($wp_roles) && ! empty($wp_roles->roles)) {
149
+ foreach ($wp_roles->roles as $role => $info) {
150
+
151
+ // Get the user role
152
+ $userRole = get_role($role);
153
+
154
+ // Map new capabilities
155
+ if ($userRole->has_cap('easingslider_add_slider')) {
156
+ $userRole->add_cap('easingslider_publish_sliders');
157
+ }
158
+ if ($userRole->has_cap('easingslider_discover_extensions')) {
159
+ $userRole->add_cap('easingslider_manage_addons');
160
+ }
161
+
162
+ // Remove/cleanup all previous capabilities
163
+ $userRole->remove_cap('easingslider_add_slider');
164
+ $userRole->remove_cap('easingslider_delete_slider');
165
+ $userRole->remove_cap('easingslider_duplicate_slider');
166
+ $userRole->remove_cap('easingslider_edit_slider');
167
+ $userRole->remove_cap('easingslider_edit_settings');
168
+ $userRole->remove_cap('easingslider_discover_extensions');
169
+ $userRole->remove_cap('easingslider_manage_extensions');
170
+
171
+ }
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Upgrades the plugin sliders
177
+ *
178
+ * @return void
179
+ */
180
+ protected function upgradeSliders()
181
+ {
182
+ // Get sliders
183
+ $sliders = Easing_Slider()->sliders();
184
+
185
+ // Get old sliders
186
+ $oldSliders = $this->getOldSliders();
187
+
188
+ /**
189
+ * We're actually using the same post type as previous versions of Easing Slider,
190
+ * so instead of creating entirely new sliders, we're upgrading the old ones to our new metadata format.
191
+ */
192
+ foreach ($oldSliders as $oldSlider) {
193
+
194
+ // New data
195
+ $data = array();
196
+
197
+ // Map linear values
198
+ $data['post_title'] = get_the_title($oldSlider->ID);
199
+ $data['type'] = 'media';
200
+ $data['slides'] = $oldSlider->slides;
201
+ $data['responsive'] = true;
202
+ $data['image_resizing'] = true;
203
+ $data['auto_height'] = false;
204
+ $data['lazy_loading'] = true;
205
+
206
+ // Map dynamic values
207
+ $data = $this->setSliderAttribute($data, 'randomize', $oldSlider, 'general', 'randomize');
208
+ $data = $this->setSliderAttribute($data, 'width', $oldSlider, 'dimensions', 'width');
209
+ $data = $this->setSliderAttribute($data, 'height', $oldSlider, 'dimensions', 'height');
210
+ $data = $this->setSliderAttribute($data, 'full_width', $oldSlider, 'dimensions', 'full_width');
211
+ $data = $this->setSliderAttribute($data, 'background_images', $oldSlider, 'dimensions', 'background_images');
212
+ $data = $this->setSliderAttribute($data, 'transition_effect', $oldSlider, 'transitions', 'effect');
213
+ $data = $this->setSliderAttribute($data, 'transition_duration', $oldSlider, 'transitions', 'duration');
214
+ $data = $this->setSliderAttribute($data, 'arrows', $oldSlider, 'navigation', 'arrows');
215
+ $data = $this->setSliderAttribute($data, 'arrows_hover', $oldSlider, 'navigation', 'arrows_hover');
216
+ $data = $this->setSliderAttribute($data, 'arrows_position', $oldSlider, 'navigation', 'arrows_position');
217
+ $data = $this->setSliderAttribute($data, 'pagination', $oldSlider, 'navigation', 'pagination');
218
+ $data = $this->setSliderAttribute($data, 'pagination_hover', $oldSlider, 'navigation', 'pagination_hover');
219
+ $data = $this->setSliderAttribute($data, 'pagination_position', $oldSlider, 'navigation', 'pagination_position');
220
+ $data = $this->setSliderAttribute($data, 'pagination_location', $oldSlider, 'navigation', 'pagination_location');
221
+ $data = $this->setSliderAttribute($data, 'playback_enabled', $oldSlider, 'playback', 'enabled');
222
+ $data = $this->setSliderAttribute($data, 'playback_pause', $oldSlider, 'playback', 'pause');
223
+
224
+ // Update the slider with new data
225
+ $sliders->update($oldSlider->ID, $data);
226
+
227
+ // Delete old slider meta
228
+ delete_post_meta($oldSlider->ID, '_easingslider_slides', true);
229
+ delete_post_meta($oldSlider->ID, '_easingslider_general', true);
230
+ delete_post_meta($oldSlider->ID, '_easingslider_dimensions', true);
231
+ delete_post_meta($oldSlider->ID, '_easingslider_transitions', true);
232
+ delete_post_meta($oldSlider->ID, '_easingslider_navigation', true);
233
+ delete_post_meta($oldSlider->ID, '_easingslider_playback', true);
234
+
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Sets a slider attribute, if the old slider value exists.
240
+ *
241
+ * @param array $slider
242
+ * @param string $key
243
+ * @param object $oldSlider
244
+ * @param string $oldSection
245
+ * @param string $oldKey
246
+ * @return array
247
+ */
248
+ protected function setSliderAttribute($slider, $key, $oldSlider, $oldSection, $oldValue)
249
+ {
250
+ if (isset($oldSlider->{$oldSection}->{$oldValue})) {
251
+ $slider[$key] = $oldSlider->{$oldSection}->{$oldValue};
252
+ }
253
+
254
+ return $slider;
255
+ }
256
+
257
+ /**
258
+ * Gets the old sliders
259
+ *
260
+ * @return array
261
+ */
262
+ protected function getOldSliders()
263
+ {
264
+ // Get sliders
265
+ $sliders = array();
266
+
267
+ // Query posts
268
+ $wpQuery = new WP_Query(array('post_type' => 'easingslider'));
269
+
270
+ // Loop through each post
271
+ if ($wpQuery->have_posts()) {
272
+ while($wpQuery->have_posts()) {
273
+
274
+ $wpQuery->the_post();
275
+
276
+ // Get post ID
277
+ $id = get_the_ID();
278
+
279
+ // Get slider
280
+ $slider = (object) array(
281
+ 'ID' => $id
282
+ );
283
+
284
+ // Add metadata
285
+ $slider->slides = get_post_meta($id, '_easingslider_slides', true);
286
+ $slider->general = get_post_meta($id, '_easingslider_general', true);
287
+ $slider->dimensions = get_post_meta($id, '_easingslider_dimensions', true);
288
+ $slider->transitions = get_post_meta($id, '_easingslider_transitions', true);
289
+ $slider->navigation = get_post_meta($id, '_easingslider_navigation', true);
290
+ $slider->playback = get_post_meta($id, '_easingslider_playback', true);
291
+
292
+ // Add to sliders
293
+ $sliders[] = $slider;
294
+
295
+ }
296
+ }
297
+
298
+ return $sliders;
299
+ }
300
+
301
+ /**
302
+ * Handles the upgrade
303
+ *
304
+ * @return void
305
+ */
306
+ protected function doUpgrade()
307
+ {
308
+ $this->setupUpgradeNotice();
309
+
310
+ $this->migrateLicense();
311
+
312
+ $this->upgradeCapabilities();
313
+
314
+ $this->upgradeSettings();
315
+
316
+ $this->upgradeSliders();
317
+ }
318
+ }
src/Plugin/Admin/Upgrades/Upgrader.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Upgrades;
4
+
5
+ use EasingSlider\Foundation\Admin\Upgrades\Upgrader as BaseUpgrader;
6
+ use EasingSlider\Plugin\Contracts\Options\Version;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ abstract class Upgrader extends BaseUpgrader
16
+ {
17
+ /**
18
+ * Constructor
19
+ *
20
+ * @param \EasingSlider\Plugin\Contracts\Options\Version $version
21
+ * @return void
22
+ */
23
+ public function __construct(Version $version)
24
+ {
25
+ parent::__construct($version);
26
+ }
27
+ }
src/Plugin/Admin/Upgrades/Upgrades.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Upgrades;
4
+
5
+ use EasingSlider\Foundation\Admin\Upgrades\Upgrades as BaseUpgrades;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class Upgrades extends BaseUpgrades
15
+ {
16
+ /**
17
+ * Boot
18
+ *
19
+ * @return void
20
+ */
21
+ protected function boot()
22
+ {
23
+ $this->upgraders[] = $this->plugin->make('\EasingSlider\Plugin\Admin\Upgrades\UpgradeTo300');
24
+ }
25
+ }
src/Plugin/Admin/Validators/License.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Validators;
4
+
5
+ use EasingSlider\Foundation\Admin\Validators\Validator;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class License extends Validator
15
+ {
16
+ /**
17
+ * Gets the validation rules
18
+ *
19
+ * @return array
20
+ */
21
+ protected function getRules()
22
+ {
23
+ return apply_filters('easingslider_admin_license_validation_rules', array(
24
+ 'key' => 'string',
25
+ 'status' => 'string'
26
+ ));
27
+ }
28
+ }
src/Plugin/Admin/Validators/Settings.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Validators;
4
+
5
+ use EasingSlider\Foundation\Admin\Validators\Validator;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class Settings extends Validator
15
+ {
16
+ /**
17
+ * Gets the validation rules
18
+ *
19
+ * @return array
20
+ */
21
+ protected function getRules()
22
+ {
23
+ return apply_filters('easingslider_admin_settings_validation_rules', array(
24
+ 'load_in_footer' => 'boolean',
25
+ 'remove_data' => 'boolean'
26
+ ));
27
+ }
28
+ }
src/Plugin/Admin/Validators/Slider.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Admin\Validators;
4
+
5
+ use EasingSlider\Foundation\Admin\Validators\Validator;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class Slider extends Validator
15
+ {
16
+ /**
17
+ * Gets the validation rules
18
+ *
19
+ * @return array
20
+ */
21
+ protected function getRules()
22
+ {
23
+ return apply_filters('easingslider_admin_slider_validation_rules', array(
24
+ 'post_title' => 'string',
25
+ 'post_type' => 'string',
26
+ 'post_status' => 'string',
27
+ 'type' => 'string',
28
+ 'slides' => 'decode_json_array',
29
+ 'randomize' => 'boolean',
30
+ 'width' => 'integer',
31
+ 'height' => 'integer',
32
+ 'full_width' => 'boolean',
33
+ 'image_resizing' => 'boolean',
34
+ 'auto_height' => 'boolean',
35
+ 'transition_effect' => 'string',
36
+ 'transition_duration' => 'integer',
37
+ 'arrows' => 'boolean',
38
+ 'arrows_hover' => 'boolean',
39
+ 'arrows_position' => 'string',
40
+ 'pagination' => 'boolean',
41
+ 'pagination_hover' => 'boolean',
42
+ 'pagination_position' => 'string',
43
+ 'pagination_location' => 'string',
44
+ 'lazy_loading' => 'boolean',
45
+ 'playback_enabled' => 'boolean',
46
+ 'playback_pause' => 'integer'
47
+ ));
48
+ }
49
+ }
src/Plugin/Assets/PublicAssets.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Assets;
4
+
5
+ use EasingSlider\Foundation\Assets\Assets as BaseAssets;
6
+ use EasingSlider\Plugin\Contracts\Options\Settings;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class PublicAssets extends BaseAssets
16
+ {
17
+ /**
18
+ * Settings
19
+ *
20
+ * @var \EasingSlider\Plugin\Contracts\Options\Settings
21
+ */
22
+ protected $settings;
23
+
24
+ /**
25
+ * Constructor
26
+ *
27
+ * @param \EasingSlider\Plugin\Options\Settings $settings
28
+ * @return void
29
+ */
30
+ public function __construct(Settings $settings)
31
+ {
32
+ $this->settings = $settings;
33
+
34
+ $this->defineHooks();
35
+ }
36
+
37
+ /**
38
+ * Define hooks
39
+ *
40
+ * @return void
41
+ */
42
+ protected function defineHooks()
43
+ {
44
+ add_action('wp_enqueue_scripts', array($this, 'enqueue'));
45
+ }
46
+
47
+ /**
48
+ * Checks if we should load our assets in the footer, based on user settings
49
+ *
50
+ * @return boolean
51
+ */
52
+ protected function loadInFooter()
53
+ {
54
+ if (isset($this->settings['load_in_footer'])) {
55
+ if (true === $this->settings['load_in_footer'] && ! did_action('easingslider_render_slider')) {
56
+ return true;
57
+ }
58
+ }
59
+
60
+ return false;
61
+ }
62
+
63
+ /**
64
+ * Enqueues the assets
65
+ *
66
+ * @return void
67
+ */
68
+ public function enqueue()
69
+ {
70
+ /**
71
+ * If we've set the asset loading to load in footer but we haven't displayed a slider on this page, let's bail.
72
+ * This prevents the assets from loading when they aren't needed.
73
+ *
74
+ * Otherwise, by default, assets will be loaded on every page in the header.
75
+ */
76
+ if ($this->loadInFooter()) {
77
+ add_action('wp_footer', array($this, 'enqueue'));
78
+ return;
79
+ }
80
+
81
+ // Get the suffix
82
+ $suffix = $this->getSuffix();
83
+
84
+ // Enqueue our assets
85
+ wp_enqueue_style('easingslider', EASINGSLIDER_ASSETS_URL ."css/public{$suffix}.css", false, EASINGSLIDER_VERSION);
86
+ wp_enqueue_script('easingslider', EASINGSLIDER_ASSETS_URL ."js/public{$suffix}.js", array('jquery'), EASINGSLIDER_VERSION);
87
+
88
+ // Trigger action for our extensions
89
+ do_action('easingslider_enqueue_assets', $suffix);
90
+ }
91
+ }
src/Plugin/Capabilities/Capabilities.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Capabilities;
4
+
5
+ use EasingSlider\Foundation\Capabilities\Capabilities as BaseCapabilities;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class Capabilities extends BaseCapabilities
15
+ {
16
+ /**
17
+ * Gets the capabilities
18
+ *
19
+ * @return array
20
+ */
21
+ protected function getCapabilities()
22
+ {
23
+ return apply_filters('easingslider_capabilities', array(
24
+ 'easingslider_publish_sliders',
25
+ 'easingslider_edit_sliders',
26
+ 'easingslider_duplicate_sliders',
27
+ 'easingslider_delete_sliders',
28
+ 'easingslider_manage_settings',
29
+ 'easingslider_manage_addons'
30
+ ));
31
+ }
32
+ }
src/Plugin/Contracts/Admin/Validators/License.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Contracts\Admin\Validators;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Validators\Validator;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface License extends Validator
15
+ {
16
+ //
17
+ }
src/Plugin/Contracts/Admin/Validators/Settings.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Contracts\Admin\Validators;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Validators\Validator;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface Settings extends Validator
15
+ {
16
+ //
17
+ }
src/Plugin/Contracts/Admin/Validators/Slider.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Contracts\Admin\Validators;
4
+
5
+ use EasingSlider\Foundation\Contracts\Admin\Validators\Validator;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface Slider extends Validator
15
+ {
16
+ //
17
+ }
src/Plugin/Contracts/Options/License.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Contracts\Options;
4
+
5
+ use EasingSlider\Foundation\Contracts\Options\OptionArray as OptionArrayContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface License extends OptionArrayContract
15
+ {
16
+ /**
17
+ * Gets the license key with all characters hidden except for the last 4.
18
+ *
19
+ * @return string
20
+ */
21
+ public function maskedKey();
22
+ }
src/Plugin/Contracts/Options/Settings.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Contracts\Options;
4
+
5
+ use EasingSlider\Foundation\Contracts\Options\OptionArray as OptionArrayContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface Settings extends OptionArrayContract
15
+ {
16
+ //
17
+ }
src/Plugin/Contracts/Options/UpgradeLicense.php ADDED
File without changes
src/Plugin/Contracts/Options/Version.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Contracts\Options;
4
+
5
+ use EasingSlider\Foundation\Contracts\Options\Option as OptionContract;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ interface Version extends OptionContract
15
+ {
16
+ //
17
+ }
src/Plugin/Models/Slider.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Models;
4
+
5
+ use EasingSlider\Foundation\Models\Model;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class Slider extends Model
15
+ {
16
+ /**
17
+ * Sets the model defaults
18
+ *
19
+ * @return array
20
+ */
21
+ public function getDefaults()
22
+ {
23
+ return apply_filters('easingslider_slider_defaults', array(
24
+ 'type' => 'media',
25
+ 'slides' => array(),
26
+ 'randomize' => false,
27
+ 'width' => 640,
28
+ 'height' => 400,
29
+ 'responsive' => true,
30
+ 'full_width' => false,
31
+ 'image_resizing' => true,
32
+ 'auto_height' => false,
33
+ 'transition_effect' => 'fade',
34
+ 'transition_duration' => 400,
35
+ 'arrows' => true,
36
+ 'arrows_hover' => false,
37
+ 'arrows_position' => 'inside',
38
+ 'pagination' => true,
39
+ 'pagination_hover' => false,
40
+ 'pagination_position' => 'inside',
41
+ 'pagination_location' => 'bottom-center',
42
+ 'lazy_loading' => true,
43
+ 'playback_enabled' => true,
44
+ 'playback_pause' => 4000
45
+ ));
46
+ }
47
+ }
src/Plugin/Options/License.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Options;
4
+
5
+ use EasingSlider\Foundation\Options\OptionArray;
6
+ use EasingSlider\Plugin\Contracts\Options\License as LicenseContract;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class License extends OptionArray implements LicenseContract
16
+ {
17
+ /**
18
+ * Name
19
+ *
20
+ * @var string
21
+ */
22
+ protected $name = 'easingslider_license';
23
+
24
+ /**
25
+ * Gets the license key with all characters hidden except for the last 4.
26
+ *
27
+ * @return string
28
+ */
29
+ public function maskedKey()
30
+ {
31
+ $licenseKey = $this->offsetGet('key');
32
+
33
+ // Get the key length for character counting
34
+ $keyLength = strlen($licenseKey);
35
+
36
+ // Generate the masked key
37
+ $maskedKey = str_repeat('*', $keyLength - 4) . substr($licenseKey, $keyLength - 4, 4);
38
+
39
+ echo $maskedKey;
40
+ }
41
+
42
+ /**
43
+ * Gets the default settings
44
+ *
45
+ * @return mixed
46
+ */
47
+ public function getDefaults()
48
+ {
49
+ return array(
50
+ 'key' => '',
51
+ 'status' => ''
52
+ );
53
+ }
54
+ }
src/Plugin/Options/Settings.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Options;
4
+
5
+ use EasingSlider\Foundation\Options\OptionArray;
6
+ use EasingSlider\Plugin\Contracts\Options\Settings as SettingsContract;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class Settings extends OptionArray implements SettingsContract
16
+ {
17
+ /**
18
+ * Name
19
+ *
20
+ * @var string
21
+ */
22
+ protected $name = 'easingslider_settings';
23
+
24
+ /**
25
+ * Gets the default settings
26
+ *
27
+ * @return mixed
28
+ */
29
+ public function getDefaults()
30
+ {
31
+ return apply_filters('easingslider_default_settings', array(
32
+ 'load_in_footer' => false,
33
+ 'remove_data' => false
34
+ ));
35
+ }
36
+ }
src/Plugin/Options/UpgradeLicense.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Options;
4
+
5
+ use EasingSlider\Foundation\Options\Option;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class UpgradeLicense extends Option
15
+ {
16
+ /**
17
+ * Name
18
+ *
19
+ * @var string
20
+ */
21
+ protected $name = 'easingslider_show_upgrade_license_notice';
22
+
23
+ /**
24
+ * Gets the default settings
25
+ *
26
+ * @return mixed
27
+ */
28
+ public function getDefaults()
29
+ {
30
+ return true;
31
+ }
32
+ }
src/Plugin/Options/Version.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Options;
4
+
5
+ use EasingSlider\Foundation\Options\Option;
6
+ use EasingSlider\Plugin\Contracts\Options\Version as VersionContract;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class Version extends Option implements VersionContract
16
+ {
17
+ /**
18
+ * Name
19
+ *
20
+ * @var string
21
+ */
22
+ protected $name = 'easingslider_version';
23
+
24
+ /**
25
+ * Gets the default settings
26
+ *
27
+ * @return mixed
28
+ */
29
+ public function getDefaults()
30
+ {
31
+ return EASINGSLIDER_VERSION;
32
+ }
33
+ }
src/Plugin/Plugin.php ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin;
4
+
5
+ use EasingSlider\Foundation\Plugin as BasePlugin;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ final class Plugin extends BasePlugin
15
+ {
16
+ /**
17
+ * Activator
18
+ *
19
+ * @var \EasingSlider\Foundation\Contracts\Activation\Activator
20
+ */
21
+ protected $activator;
22
+
23
+ /**
24
+ * Admin
25
+ *
26
+ * @var \EasingSlider\Foundation\Contracts\Admin\Admin
27
+ */
28
+ protected $admin;
29
+
30
+ /**
31
+ * Assets
32
+ *
33
+ * @var \EasingSlider\Foundation\Contracts\Assets\Assets
34
+ */
35
+ protected $assets;
36
+
37
+ /**
38
+ * Capabilities
39
+ *
40
+ * @var \EasingSlider\Foundation\Contracts\Capabilities\Capabilities
41
+ */
42
+ protected $capabilities;
43
+
44
+ /**
45
+ * License
46
+ *
47
+ * @var \EasingSlider\Plugin\Contracts\Options\License
48
+ */
49
+ protected $license;
50
+
51
+ /**
52
+ * Settings
53
+ *
54
+ * @var \EasingSlider\Plugin\Contracts\Options\Settings
55
+ */
56
+ protected $settings;
57
+
58
+ /**
59
+ * Shortcode
60
+ *
61
+ * @var \EasingSlider\Foundation\Contracts\Shortcodes\Shortcode
62
+ */
63
+ protected $shortcode;
64
+
65
+ /**
66
+ * Sliders
67
+ *
68
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
69
+ */
70
+ protected $sliders;
71
+
72
+ /**
73
+ * Template Loader
74
+ *
75
+ * @var \EasingSlider\Foundation\Contracts\TemplateLoaders\TemplateLoader
76
+ */
77
+ protected $templateLoader;
78
+
79
+ /**
80
+ * Uninstaller
81
+ *
82
+ * @var \EasingSlider\Foundation\Contracts\Uninstallation\Uninstaller
83
+ */
84
+ protected $uninstaller;
85
+
86
+ /**
87
+ * Version
88
+ *
89
+ * @var \EasingSlider\Plugin\Contracts\Options\Version
90
+ */
91
+ protected $version;
92
+
93
+ /**
94
+ * Widget
95
+ *
96
+ * @var \EasingSlider\Foundation\Contracts\Widgets\Widget
97
+ */
98
+ protected $widget;
99
+
100
+ /**
101
+ * Aliases
102
+ *
103
+ * @var array
104
+ */
105
+ protected $aliases = array(
106
+ '\EasingSlider\Foundation\Contracts\Activation\Activator' => '\EasingSlider\Plugin\Activation\Activator',
107
+ '\EasingSlider\Foundation\Contracts\Admin\Admin' => '\EasingSlider\Plugin\Admin\Admin',
108
+ '\EasingSlider\Foundation\Contracts\Assets\Assets' => '\EasingSlider\Plugin\Assets\PublicAssets',
109
+ '\EasingSlider\Foundation\Contracts\Capabilities\Capabilities' => '\EasingSlider\Plugin\Capabilities\Capabilities',
110
+ '\EasingSlider\Foundation\Contracts\Plugin' => '\EasingSlider\Plugin\Plugin',
111
+ '\EasingSlider\Foundation\Contracts\Repositories\Repository' => '\EasingSlider\Plugin\Repositories\Sliders',
112
+ '\EasingSlider\Foundation\Contracts\Shortcodes\Shortcode' => '\EasingSlider\Plugin\Shortcodes\Slider',
113
+ '\EasingSlider\Foundation\Contracts\TemplateLoaders\TemplateLoader' => '\EasingSlider\Plugin\TemplateLoaders\TemplateLoader',
114
+ '\EasingSlider\Foundation\Contracts\Uninstallation\Uninstaller' => '\EasingSlider\Plugin\Uninstallation\Uninstaller',
115
+ '\EasingSlider\Foundation\Contracts\Widgets\Widget' => '\EasingSlider\Plugin\Widgets\Slider',
116
+ '\EasingSlider\Plugin\Contracts\Options\License' => '\EasingSlider\Plugin\Options\License',
117
+ '\EasingSlider\Plugin\Contracts\Options\Settings' => '\EasingSlider\Plugin\Options\Settings',
118
+ '\EasingSlider\Plugin\Contracts\Options\Version' => '\EasingSlider\Plugin\Options\Version'
119
+ );
120
+
121
+ /**
122
+ * Singletons
123
+ *
124
+ * @var array
125
+ */
126
+ protected $singletons = array(
127
+ '\EasingSlider\Foundation\Contracts\Activation\Activator',
128
+ '\EasingSlider\Foundation\Contracts\Admin\Admin',
129
+ '\EasingSlider\Foundation\Contracts\Assets\Assets',
130
+ '\EasingSlider\Foundation\Contracts\Capabilities\Capabilities',
131
+ '\EasingSlider\Foundation\Contracts\Plugin',
132
+ '\EasingSlider\Foundation\Contracts\Repositories\Repository',
133
+ '\EasingSlider\Foundation\Contracts\Shortcodes\Shortcode',
134
+ '\EasingSlider\Foundation\Contracts\TemplateLoaders\TemplateLoader',
135
+ '\EasingSlider\Foundation\Contracts\Uninstallation\Uninstaller',
136
+ '\EasingSlider\Foundation\Contracts\Widgets\Widget',
137
+ '\EasingSlider\Plugin\Contracts\Options\License',
138
+ '\EasingSlider\Plugin\Contracts\Options\Settings',
139
+ '\EasingSlider\Plugin\Contracts\Options\Version'
140
+ );
141
+
142
+ /**
143
+ * Boots the plugin
144
+ *
145
+ * @return void
146
+ */
147
+ protected function boot()
148
+ {
149
+ $this->setl10n();
150
+
151
+ $this->bootComponents();
152
+ }
153
+
154
+ /**
155
+ * Set localization
156
+ *
157
+ * @return void
158
+ */
159
+ protected function setl10n()
160
+ {
161
+ // Load plugin textdomain
162
+ load_plugin_textdomain('easingslider', false, plugin_basename(EASINGSLIDER_PLUGIN_FILE) . '/languages/');
163
+ }
164
+
165
+ /**
166
+ * Boot components
167
+ *
168
+ * @return void
169
+ */
170
+ protected function bootComponents()
171
+ {
172
+ $this->activator = $this->make('\EasingSlider\Foundation\Contracts\Activation\Activator');
173
+ $this->assets = $this->make('\EasingSlider\Foundation\Contracts\Assets\Assets');
174
+ $this->capabilities = $this->make('\EasingSlider\Foundation\Contracts\Capabilities\Capabilities');
175
+ $this->license = $this->make('\EasingSlider\Plugin\Contracts\Options\License');
176
+ $this->settings = $this->make('\EasingSlider\Plugin\Contracts\Options\Settings');
177
+ $this->shortcode = $this->make('\EasingSlider\Foundation\Contracts\Shortcodes\Shortcode');
178
+ $this->sliders = $this->make('\EasingSlider\Foundation\Contracts\Repositories\Repository');
179
+ $this->templateLoader = $this->make('\EasingSlider\Foundation\Contracts\TemplateLoaders\TemplateLoader');
180
+ $this->uninstaller = $this->make('\EasingSlider\Foundation\Contracts\Uninstallation\Uninstaller');
181
+ $this->version = $this->make('\EasingSlider\Plugin\Contracts\Options\Version');
182
+ $this->widget = $this->make('\EasingSlider\Foundation\Contracts\Widgets\Widget');
183
+
184
+ if (is_admin()) {
185
+ $this->admin = $this->make('\EasingSlider\Foundation\Contracts\Admin\Admin');
186
+ }
187
+ }
188
+ }
src/Plugin/Repositories/Sliders.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Repositories;
4
+
5
+ use EasingSlider\Foundation\Repositories\PostType;
6
+ use EasingSlider\Plugin\Models\Slider;
7
+
8
+ /**
9
+ * Exit if accessed directly
10
+ */
11
+ if ( ! defined('ABSPATH')) {
12
+ exit;
13
+ }
14
+
15
+ class Sliders extends PostType
16
+ {
17
+ /**
18
+ * Post Type
19
+ *
20
+ * @var string
21
+ */
22
+ protected $postType = 'easingslider';
23
+
24
+ /**
25
+ * Meta Key
26
+ *
27
+ * @var string
28
+ */
29
+ protected $metaKey = '_easingslider';
30
+
31
+ /**
32
+ * Gets the post type label
33
+ *
34
+ * @return string
35
+ */
36
+ protected function getPostTypeLabel()
37
+ {
38
+ return __('Sliders', 'easingslider');
39
+ }
40
+
41
+ /**
42
+ * Gets a new model instance
43
+ *
44
+ * @return \EasingSlider\Foundation\Models\ModelContract
45
+ */
46
+ protected function newModel()
47
+ {
48
+ return new Slider();
49
+ }
50
+ }
src/Plugin/Shortcodes/Slider.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Shortcodes;
4
+
5
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
6
+ use EasingSlider\Foundation\Shortcodes\Shortcode;
7
+ use EasingSlider\Plugin\Views\Slider as SliderView;
8
+
9
+ /**
10
+ * Exit if accessed directly
11
+ */
12
+ if ( ! defined('ABSPATH')) {
13
+ exit;
14
+ }
15
+
16
+ class Slider extends Shortcode
17
+ {
18
+ /**
19
+ * Tag
20
+ *
21
+ * @var string
22
+ */
23
+ protected $tag = 'easingslider';
24
+
25
+ /**
26
+ * Sliders
27
+ *
28
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
29
+ */
30
+ protected $sliders;
31
+
32
+ /**
33
+ * Constructor
34
+ *
35
+ * @param \EasingSlider\Foundation\Contracts\Repositories\Repository $sliders
36
+ * @return void
37
+ */
38
+ public function __construct(Repository $sliders)
39
+ {
40
+ $this->sliders = $sliders;
41
+
42
+ parent::__construct();
43
+ }
44
+
45
+ /**
46
+ * Renders the shortcode
47
+ *
48
+ * @param array $atts
49
+ * @return string
50
+ */
51
+ public function render($atts = array())
52
+ {
53
+ // Default shortcode attributes
54
+ $defaults = apply_filters('easingslider_shortcode_defaults', array('id' => false));
55
+
56
+ // Combine shortcode attributes with defaults
57
+ $atts = (object) shortcode_atts($defaults, $atts);
58
+
59
+ // Continue if we have an ID
60
+ if ( ! empty($atts->id)) {
61
+
62
+ // Find the slider
63
+ $slider = $this->sliders->find($atts->id);
64
+
65
+ // Continue if we have a slider. Otheriwse display error message if no slider has been found
66
+ if ($slider) {
67
+
68
+ // Start output buffer
69
+ ob_start();
70
+
71
+ // Display the slider
72
+ $view = new SliderView($slider);
73
+ $view->display();
74
+
75
+ // Return output buffer
76
+ return ob_get_clean();
77
+
78
+ } else {
79
+
80
+ // Show admins an error
81
+ if (is_super_admin()) {
82
+ return sprintf(__('<p><strong>The slider specified (ID #%d) could not be found.</strong></p>', 'easingslider'), $atts->id);
83
+ }
84
+
85
+ }
86
+
87
+ }
88
+ }
89
+ }
src/Plugin/Support/AttachmentImageResizer.php ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Support;
4
+
5
+ /**
6
+ * Exit if accessed directly
7
+ */
8
+ if ( ! defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ class AttachmentImageResizer
13
+ {
14
+ /**
15
+ * The attachment image ID
16
+ *
17
+ * @var int
18
+ */
19
+ protected $attachmentId;
20
+
21
+ /**
22
+ * Constructor
23
+ *
24
+ * @param int $attachmentId
25
+ * @return void
26
+ */
27
+ public function __construct($attachmentId)
28
+ {
29
+ $this->attachmentId = $attachmentId;
30
+ }
31
+
32
+ /**
33
+ * Resizes an attachment image
34
+ *
35
+ * @param int $width
36
+ * @param int $height
37
+ * @param boolean $crop
38
+ * @param int $quality
39
+ * @return array
40
+ */
41
+ public function resize($width, $height, $crop = true, $quality = 100)
42
+ {
43
+ global $wpdb;
44
+
45
+ // Get the attachment
46
+ $attachmentUrl = wp_get_attachment_url($this->attachmentId, 'full');
47
+
48
+ // Bail if we don't have an attachment URL
49
+ if ( ! $attachmentUrl) {
50
+ return array('url' => $attachmentUrl, 'width' => $width, 'height' => $height);
51
+ }
52
+
53
+ // Get the image file path
54
+ $filePath = parse_url($attachmentUrl);
55
+ $filePath = $_SERVER['DOCUMENT_ROOT'] . $filePath['path'];
56
+
57
+ // Additional handling for multisite
58
+ if (is_multisite()) {
59
+ global $blog_id;
60
+ $blogDetails = get_blog_details($blog_id);
61
+ $filePath = str_replace($blogDetails->path . 'files/', '/wp-content/blogs.dir/'. $blog_id .'/files/', $filePath);
62
+ }
63
+
64
+ // Destination width and height variables
65
+ $destWidth = apply_filters('easingslider_resize_image_width', $width, $attachmentUrl);
66
+ $destHeight = apply_filters('easingslider_resize_image_height', $height, $attachmentUrl);
67
+
68
+ // File name suffix (appended to original file name)
69
+ $suffix = "{$destWidth}x{$destHeight}";
70
+
71
+ // Some additional info about the image
72
+ $info = pathinfo($filePath);
73
+ $dir = $info['dirname'];
74
+ $ext = $info['extension'];
75
+ $name = wp_basename($filePath, ".$ext");
76
+
77
+ // Suffix applied to filename
78
+ $suffix = "{$destWidth}x{$destHeight}";
79
+
80
+ // Get the destination file name
81
+ $destFileName = "{$dir}/{$name}-{$suffix}.{$ext}";
82
+
83
+ // Execute the resizing if resized image doesn't already exist.
84
+ if ( ! file_exists($destFileName)) {
85
+
86
+ // Load Wordpress Image Editor
87
+ $editor = wp_get_image_editor($filePath);
88
+
89
+ // Bail if we encounter a WP_Error
90
+ if (is_wp_error($editor)) {
91
+ return array('url' => $attachmentUrl, 'width' => $width, 'height' => $height);
92
+ }
93
+
94
+ // Set the quality
95
+ $editor->set_quality($quality);
96
+
97
+ // Get the original image size
98
+ $size = $editor->get_size();
99
+ $origWidth = $size['width'];
100
+ $origHeight = $size['height'];
101
+
102
+ $srcX = $srcY = 0;
103
+ $srcW = $origWidth;
104
+ $srcH = $origHeight;
105
+
106
+ // Handle cropping
107
+ if ($crop) {
108
+
109
+ $cmpX = $origWidth / $destWidth;
110
+ $cmpY = $origHeight / $destHeight;
111
+
112
+ // Calculate x or y coordinate, and width or height of source
113
+ if ($cmpX > $cmpY) {
114
+ $srcW = round($origWidth / $cmpX * $cmpY);
115
+ $srcX = round(($origWidth - ($origWidth / $cmpX * $cmpY)) / 2);
116
+ }
117
+ else if ($cmpY > $cmpX) {
118
+ $srcH = round($origHeight / $cmpY * $cmpX);
119
+ $srcY = round(($origHeight - ($origHeight / $cmpY * $cmpX)) / 2);
120
+ }
121
+
122
+ }
123
+
124
+ // Time to crop the image
125
+ $editor->crop($srcX, $srcY, $srcW, $srcH, $destWidth, $destHeight);
126
+
127
+ // Now let's save the image
128
+ $saved = $editor->save($destFileName);
129
+
130
+ // Get resized image information
131
+ $resizedUrl = str_replace(basename($attachmentUrl), basename($saved['path']), $attachmentUrl);
132
+ $resizedWidth = $saved['width'];
133
+ $resizedHeight = $saved['height'];
134
+ $resizedType = $saved['mime-type'];
135
+
136
+ /**
137
+ * Add the resized dimensions to original image metadata
138
+ *
139
+ * This ensures our resized images are deleted when the original image is deleted from the Media Library
140
+ */
141
+ $metadata = wp_get_attachment_metadata($this->attachmentId);
142
+ if (isset($metadata['image_meta'])) {
143
+ $metadata['image_meta']['resized_images'][] = $resizedWidth .'x'. $resizedHeight;
144
+ wp_update_attachment_metadata($this->attachmentId, $metadata);
145
+ }
146
+
147
+ // Create the image array
148
+ $resizedImage = array(
149
+ 'url' => $resizedUrl,
150
+ 'width' => $resizedWidth,
151
+ 'height' => $resizedHeight,
152
+ 'type' => $resizedType
153
+ );
154
+
155
+ }
156
+ else {
157
+ $resizedImage = array(
158
+ 'url' => str_replace(basename($attachmentUrl), basename($destFileName), $attachmentUrl),
159
+ 'width' => $destWidth,
160
+ 'height' => $destHeight,
161
+ 'type' => $ext
162
+ );
163
+ }
164
+
165
+ // And we're done!
166
+ return $resizedImage;
167
+ }
168
+ }
src/Plugin/TemplateLoaders/TemplateLoader.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\TemplateLoaders;
4
+
5
+ use EasingSlider\Foundation\TemplateLoaders\TemplateLoader as BaseTemplateLoader;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class TemplateLoader extends BaseTemplateLoader
15
+ {
16
+ /**
17
+ * Returns the URL to the Easing Slider templates directory
18
+ *
19
+ * @return string
20
+ */
21
+ public function getThemeTemplateDirName()
22
+ {
23
+ return apply_filters('easingslider_theme_template_dir_name', 'easingslider');
24
+ }
25
+ }
src/Plugin/Uninstallation/Uninstaller.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Uninstallation;
4
+
5
+ use EasingSlider\Foundation\Contracts\Capabilities\Capabilities;
6
+ use EasingSlider\Foundation\Contracts\Repositories\Repository;
7
+ use EasingSlider\Foundation\Uninstallation\Uninstaller as BaseUninstaller;
8
+ use EasingSlider\Plugin\Contracts\Options\License;
9
+ use EasingSlider\Plugin\Contracts\Options\Settings;
10
+ use EasingSlider\Plugin\Contracts\Options\Version;
11
+
12
+ /**
13
+ * Exit if accessed directly
14
+ */
15
+ if ( ! defined('ABSPATH')) {
16
+ exit;
17
+ }
18
+
19
+ class Uninstaller extends BaseUninstaller
20
+ {
21
+ /**
22
+ * Capabilities
23
+ *
24
+ * @var \EasingSlider\Foundation\Contracts\Capabilities\Capabilities
25
+ */
26
+ protected $capabilities;
27
+
28
+ /**
29
+ * License
30
+ *
31
+ * @var \EasingSlider\Plugin\Contracts\Options\License
32
+ */
33
+ protected $license;
34
+
35
+ /**
36
+ * Settings
37
+ *
38
+ * @var \EasingSlider\Plugin\Contracts\Options\Settings
39
+ */
40
+ protected $settings;
41
+
42
+ /**
43
+ * Sliders
44
+ *
45
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
46
+ */
47
+ protected $sliders;
48
+
49
+ /**
50
+ * Version
51
+ *
52
+ * @var \EasingSlider\Plugin\Contracts\Options\Version
53
+ */
54
+ protected $version;
55
+
56
+ /**
57
+ * Constructor
58
+ *
59
+ * @param \EasingSlider\Foundation\Contracts\Capabilities\Capabilities $capabilities
60
+ * @param \EasingSlider\Plugin\Contracts\Options\License $license
61
+ * @param \EasingSlider\Plugin\Contracts\Options\Settings $settings
62
+ * @param \EasingSlider\Foundation\Contracts\Repositories\Repository $sliders
63
+ * @param \EasingSlider\Plugin\Contracts\Options\Version $version
64
+ * @return void
65
+ */
66
+ public function __construct(
67
+ Capabilities $capabilities,
68
+ License $license,
69
+ Settings $settings,
70
+ Repository $sliders,
71
+ Version $version
72
+ )
73
+ {
74
+ $this->capabilities = $capabilities;
75
+ $this->license = $license;
76
+ $this->settings = $settings;
77
+ $this->sliders = $sliders;
78
+ $this->version = $version;
79
+ }
80
+
81
+ /**
82
+ * Executes uninstall
83
+ *
84
+ * @return void
85
+ */
86
+ public function uninstall()
87
+ {
88
+ $this->removeSliders();
89
+
90
+ $this->removeSettings();
91
+
92
+ $this->removeCapabilities();
93
+
94
+ $this->removeLicense();
95
+
96
+ $this->removeVersion();
97
+
98
+ $this->removeTransients();
99
+ }
100
+
101
+ /**
102
+ * Removes all sliders
103
+ *
104
+ * @return void
105
+ */
106
+ protected function removeSliders()
107
+ {
108
+ $sliders = $this->sliders->all();
109
+
110
+ foreach ($sliders as $slider) {
111
+ $this->sliders->delete($slider->ID);
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Removes the plugin settings
117
+ *
118
+ * @return void
119
+ */
120
+ protected function removeSettings()
121
+ {
122
+ $this->settings->delete();
123
+ }
124
+
125
+ /**
126
+ * Removes the plugin capabilities
127
+ *
128
+ * @return void
129
+ */
130
+ protected function removeCapabilities()
131
+ {
132
+ $this->capabilities->removeFromRoles();
133
+ }
134
+
135
+ /**
136
+ * Removes the plugin license
137
+ *
138
+ * @return void
139
+ */
140
+ protected function removeLicense()
141
+ {
142
+ $this->license->delete();
143
+ }
144
+
145
+ /**
146
+ * Removes the plugin version
147
+ *
148
+ * @return void
149
+ */
150
+ protected function removeVersion()
151
+ {
152
+ $this->version->delete();
153
+ }
154
+
155
+ /**
156
+ * Removes any cached transients
157
+ *
158
+ * @return void
159
+ */
160
+ protected function removeTransients()
161
+ {
162
+ delete_site_transient('easingslider_addons');
163
+ }
164
+ }
src/Plugin/Views/Slider.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Views;
4
+
5
+ use EasingSlider\Foundation\Contracts\Models\Model;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class Slider
15
+ {
16
+ /**
17
+ * Slider
18
+ *
19
+ * @var \EasingSlider\Foundation\Contracts\Models\Model;
20
+ */
21
+ protected $slider;
22
+
23
+ /**
24
+ * Constructor
25
+ *
26
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
27
+ * @return void
28
+ */
29
+ public function __construct(Model $slider)
30
+ {
31
+ $this->slider = $slider;
32
+ }
33
+
34
+ /**
35
+ * Displays the view
36
+ *
37
+ * @return void
38
+ */
39
+ public function display()
40
+ {
41
+ // Run through function
42
+ $slider = apply_filters('easingslider_pre_display_slider', $this->slider);
43
+
44
+ // Check for slides
45
+ if (0 == count($slider->slides) && is_super_admin()) {
46
+
47
+ // Display an error (to admins only) informing the user that the slider has no slides.
48
+ printf(__('<p><strong>The slider ID #%d has no slides. Cannot display the slider.</strong></p>', 'easingslider'), $slider->ID);
49
+
50
+ } else {
51
+
52
+ // Load the slider template
53
+ easingslider_get_template_part(array('slider' => $slider), 'slider');
54
+
55
+ }
56
+
57
+ // Do action
58
+ do_action('easingslider_render_slider', $slider);
59
+ }
60
+ }
src/Plugin/Widgets/Slider.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EasingSlider\Plugin\Widgets;
4
+
5
+ use EasingSlider\Foundation\Widgets\Widget;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ class Slider extends Widget
15
+ {
16
+ /**
17
+ * Shortcode
18
+ *
19
+ * @var \EasingSlider\Foundation\Contracts\Shortcodes\Shortcode
20
+ */
21
+ protected $shortcode;
22
+
23
+ /**
24
+ * Sliders
25
+ *
26
+ * @var \EasingSlider\Foundation\Contracts\Repositories\Repository
27
+ */
28
+ protected $sliders;
29
+
30
+ /**
31
+ * Boots the widget
32
+ *
33
+ * @return void
34
+ */
35
+ protected function boot()
36
+ {
37
+ // Get dependencies through plugin as WordPress doesn't allow us to inject them into widgets
38
+ $this->shortcode = Easing_Slider()->shortcode();
39
+ $this->sliders = Easing_Slider()->sliders();
40
+ }
41
+
42
+ /**
43
+ * Gets the widget name
44
+ *
45
+ * @return string
46
+ */
47
+ protected function getName()
48
+ {
49
+ return 'easingslider_widget';
50
+ }
51
+
52
+ /**
53
+ * Gets the widget title
54
+ *
55
+ * @return string
56
+ */
57
+ protected function getTitle()
58
+ {
59
+ return __('Slider', 'easingslider');
60
+ }
61
+
62
+ /**
63
+ * Gets the widget description
64
+ *
65
+ * @return string
66
+ */
67
+ protected function getDescription()
68
+ {
69
+ return __('Display a slider using a widget.', 'easingslider');
70
+ }
71
+
72
+ /**
73
+ * Updates the widget settings
74
+ *
75
+ * @param array $newInstance
76
+ * @param array $oldInstance
77
+ * @return array
78
+ */
79
+ public function update($newInstance, $oldInstance)
80
+ {
81
+ return array(
82
+ 'id' => intval($newInstance['id']),
83
+ 'title' => strip_tags($newInstance['title'])
84
+ );
85
+ }
86
+
87
+ /**
88
+ * Shows the widget settings form
89
+ *
90
+ * @param array $instance
91
+ * @return array
92
+ */
93
+ public function form($instance)
94
+ {
95
+ // Get all published sliders
96
+ $sliders = $this->sliders->all('publish');
97
+
98
+ ?>
99
+ <p>
100
+ <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'easingslider'); ?></label>
101
+ <input type="text" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" class="widefat" value="<?php if (isset($instance['title'])) echo esc_attr($instance['title']); ?>">
102
+ </p>
103
+ <p>
104
+ <label for="<?php echo $this->get_field_id('id'); ?>"><?php _e('Select Slider:', 'easingslider'); ?></label>
105
+ <select id="<?php echo $this->get_field_id('id'); ?>" name="<?php echo $this->get_field_name('id'); ?>" class="widefat">
106
+ <option value="-1"><?php _e('&#8212; Select &#8212;', 'easingslider'); ?></option>
107
+ <?php foreach ($sliders as $slider) : ?>
108
+ <option value="<?php echo esc_attr($slider->ID); ?>" <?php if (isset($instance['id'])) selected($instance['id'], $slider->ID); ?>><?php echo esc_html($slider->post_title) . sprintf(__(' (ID #%s)', 'easingslider'), $slider->ID); ?></option>
109
+ <?php endforeach; ?>
110
+ </select>
111
+ </p>
112
+ <?php
113
+ }
114
+
115
+ /**
116
+ * Displays the widget content
117
+ *
118
+ * @param array $instance
119
+ * @return void
120
+ */
121
+ public function display($instance)
122
+ {
123
+ if ( ! empty($instance['id'])) {
124
+ $this->shortcode->render(array('id' => $instance['id']));
125
+ }
126
+ }
127
+ }
src/Plugin/helpers.php ADDED
@@ -0,0 +1,530 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use EasingSlider\Foundation\Contracts\Models\Model;
4
+ use EasingSlider\Plugin\Admin\UpdateManager;
5
+ use EasingSlider\Plugin\Support\AttachmentImageResizer;
6
+
7
+ /**
8
+ * Exit if accessed directly
9
+ */
10
+ if ( ! defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ if ( ! function_exists('easingslider')) {
15
+ /**
16
+ * Alias for displaying a slider shortcode
17
+ *
18
+ * @param int $id
19
+ * @return void
20
+ */
21
+ function easingslider($id)
22
+ {
23
+ return Easing_Slider()->shortcode()->render(array('id' => $id));
24
+ }
25
+ }
26
+
27
+ if ( ! function_exists('easingslider_get_template_part')) {
28
+ /**
29
+ * Retrieves a template part
30
+ *
31
+ * @param array $data The data to be inserted
32
+ * @param string $slug The template slug
33
+ * @param string $name The template name
34
+ * @param boolean $load Whether to load the template or return it
35
+ * @return string
36
+ */
37
+ function easingslider_get_template_part($data, $slug, $name = null, $load = true)
38
+ {
39
+ $templateLoader = Easing_Slider()->templateLoader();
40
+ $templateLoader->getTemplatePart($data, $slug, $name, $load);
41
+ }
42
+ }
43
+
44
+ if ( ! function_exists('easingslider_container_classes')) {
45
+ /**
46
+ * Prints the slider container classes
47
+ *
48
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
49
+ * @return void
50
+ */
51
+ function easingslider_container_classes(Model $slider)
52
+ {
53
+ // Base classes
54
+ $classes = array(
55
+ 'easingslider',
56
+ 'easingslider-container'
57
+ );
58
+
59
+ // Full width
60
+ if (true == $slider->full_width) {
61
+ $classes[] = 'easingslider-full-width';
62
+ }
63
+
64
+ // Auto height/aspect ratio
65
+ if (true == $slider->auto_height) {
66
+ $classes[] = 'easingslider-auto-height';
67
+ } else {
68
+ $classes[] = 'easingslider-aspect-ratio';
69
+ }
70
+
71
+ // Arrows
72
+ if ($slider->arrows) {
73
+ if ($slider->arrows_hover) {
74
+ $classes[] = 'easingslider-arrows-hover';
75
+ }
76
+ if ('inside' == $slider->arrows_position) {
77
+ $classes[] = 'easingslider-arrows-inside';
78
+ } elseif ('outside' == $slider->arrows_position) {
79
+ $classes[] = 'easingslider-arrows-outside';
80
+ }
81
+ }
82
+
83
+ // Pagination
84
+ if ($slider->pagination) {
85
+ if ($slider->pagination_hover) {
86
+ $classes[] = 'easingslider-pagination-hover';
87
+ }
88
+ if ('inside' == $slider->pagination_position) {
89
+ $classes[] = 'easingslider-pagination-inside';
90
+ } elseif ('outside' == $slider->pagination_position) {
91
+ $classes[] = 'easingslider-pagination-outside';
92
+ }
93
+ $classes[] = "easingslider-pagination-{$slider->pagination_location}";
94
+ }
95
+
96
+ // Run through a filter
97
+ $classes = apply_filters('easingslider_container_classes', $classes, $slider);
98
+
99
+ // Print classes if not empty
100
+ if ( ! empty($classes)) {
101
+ echo 'class="';
102
+ echo esc_attr(implode(' ', $classes));
103
+ echo '"';
104
+ }
105
+ }
106
+ }
107
+
108
+ if ( ! function_exists('easingslider_inline_script')) {
109
+ /**
110
+ * Prints inline scripting for a slider
111
+ *
112
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
113
+ * @return void
114
+ */
115
+ function easingslider_inline_script(Model $slider)
116
+ {
117
+ $params = array(
118
+ 'width' => intval($slider->width),
119
+ 'height' => intval($slider->height),
120
+ 'singleItem' => true,
121
+ 'items' => 1,
122
+ 'itemsDesktop' => false,
123
+ 'itemsDesktopSmall' => false,
124
+ 'itemsTablet' => false,
125
+ 'itemsTabletSmall' => false,
126
+ 'itemsMobile' => false,
127
+ 'responsive' => true,
128
+ 'lazyLoad' => (true == $slider->lazy_loading) ? true : false,
129
+ 'autoPlay' => (true == $slider->playback_enabled) ? intval($slider->playback_pause) : false,
130
+ 'slideSpeed' => intval($slider->transition_duration),
131
+ 'navigation' => (true == $slider->arrows) ? true : false,
132
+ 'navigationText' => array('', ''),
133
+ 'pagination' => (true == $slider->pagination) ? true : false,
134
+ 'autoHeight' => (true == $slider->auto_height) ? true : false,
135
+ 'mouseDrag' => false,
136
+ 'touchDrag' => false,
137
+ 'addClassActive' => true,
138
+ 'transitionStyle' => ('fade' == $slider->transition_effect) ? 'fade' : false,
139
+ );
140
+
141
+ // Run through a filter
142
+ $params = apply_filters('easingslider_inline_script', $params, $slider);
143
+
144
+ // Print scripting if not empty
145
+ if ( ! empty($params)) {
146
+ ?>
147
+ <script type="text/javascript">
148
+ window.EasingSlider<?php echo esc_attr($slider->ID); ?> = <?php echo json_encode($params); ?>;
149
+ </script>
150
+ <?php
151
+ }
152
+ }
153
+ }
154
+
155
+ if ( ! function_exists('easingslider_inline_styles')) {
156
+ /**
157
+ * Prints inline styling for a slider
158
+ *
159
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
160
+ * @return void
161
+ */
162
+ function easingslider_inline_styles(Model $slider) {
163
+
164
+ // Initiate styles
165
+ $styles = '';
166
+
167
+ // Styling for "width" and "height"
168
+ $styles .= '.easingslider { ';
169
+ if (true == $slider->full_width) {
170
+ $styles .= 'width: 100%; ';
171
+ } else {
172
+ $styles .= "max-width: {$slider->width}px; ";
173
+ }
174
+ $styles .= "}\n";
175
+
176
+ // Styling for slide dimensions
177
+ if (false == $slider->auto_height) {
178
+ $styles .= '.easingslider-image { ';
179
+ $styles .= 'max-height: '. absint($slider->height) .'px; ';
180
+ $styles .= 'max-width: '. absint($slider->width) .'px; ';
181
+ $styles .= "}\n";
182
+ }
183
+
184
+ // Styling for "fade" transition speed
185
+ if ($slider->transition_effect) {
186
+ $styles .= '.easingslider-fade-in, .easingslider-fade-out { ';
187
+ $styles .= '-webkit-animation-duration: '. absint($slider->transition_duration) .'ms; ';
188
+ $styles .= '-moz-animation-duration: '. absint($slider->transition_duration) .'ms; ';
189
+ $styles .= 'animation-duration: '. absint($slider->transition_duration) .'ms; ';
190
+ $styles .= "}\n";
191
+ }
192
+
193
+ // Run through a filter
194
+ $styles = apply_filters('easingslider_inline_styles', $styles, $slider);
195
+
196
+ // Print styling if not empty
197
+ if ( ! empty($styles)) {
198
+ echo '<style type="text/css">';
199
+ echo esc_attr($styles);
200
+ echo '</style>';
201
+ }
202
+ }
203
+ }
204
+
205
+ if ( ! function_exists('easingslider_get_placeholder_pixel')) {
206
+ /**
207
+ * Returns the URL to our single pixel placeholder image
208
+ *
209
+ * @return string
210
+ */
211
+ function easingslider_get_placeholder_pixel()
212
+ {
213
+ return EASINGSLIDER_ASSETS_URL . 'images/placeholder-pixel.png';
214
+ }
215
+ }
216
+
217
+ if ( ! function_exists('easingslider_display_slide')) {
218
+ /**
219
+ * Runs the appropriate action based on the slide type.
220
+ * Should be used to display said slide type whilst remaining extensible.
221
+ *
222
+ * @param object $slide
223
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
224
+ * @return void
225
+ */
226
+ function easingslider_display_slide($slide, Model $slider)
227
+ {
228
+ // Before slide
229
+ do_action('easingslider_before_display_slide', $slide, $slider);
230
+
231
+ // Run the action
232
+ do_action("easingslider_display_{$slide->type}_slide", $slide, $slider);
233
+
234
+ // After slide
235
+ do_action('easingslider_after_display_slide', $slide, $slider);
236
+ }
237
+ }
238
+
239
+ if ( ! function_exists('easingslider_display_image_slide')) {
240
+ /**
241
+ * Displays an image slide
242
+ *
243
+ * @param object $slide
244
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
245
+ * @return void
246
+ */
247
+ function easingslider_display_image_slide($slide, Model $slider)
248
+ {
249
+ ?>
250
+ <?php if ( ! empty($slide->link) && 'none' != $slide->link) : ?><a href="<?php echo esc_attr($slide->linkUrl); ?>" target="<?php echo esc_attr($slide->linkTargetBlank); ?>"><?php endif; ?>
251
+ <?php
252
+ /**
253
+ * Here we use background images for "full width" sliders to achieve desired effect.
254
+ */
255
+ ?>
256
+ <?php if (true === $slider->lazy_loading) : ?>
257
+ <img src="<?php echo esc_attr(easingslider_get_placeholder_pixel()); ?>" data-src="<?php echo esc_attr($slide->url); ?>" alt="<?php echo esc_attr($slide->alt); ?>" title="<?php echo esc_attr($slide->title); ?>" class="easingslider-image easingslider-lazy" />
258
+ <?php else : ?>
259
+ <img src="<?php echo esc_attr($slide->url); ?>" alt="<?php echo esc_attr($slide->alt); ?>" title="<?php echo esc_attr($slide->title); ?>" class="easingslider-image" />
260
+ <?php endif; ?>
261
+ <?php if ( ! empty($slide->link) && 'none' != $slide->link) : ?></a><?php endif; ?>
262
+ <?php
263
+ }
264
+ add_action('easingslider_display_image_slide', 'easingslider_display_image_slide', 10, 2);
265
+ }
266
+
267
+ if ( ! function_exists('easingslider_resize_attachment_image')) {
268
+ /**
269
+ * Resizes an attachment image
270
+ *
271
+ * @param int $attachmentId
272
+ * @param int $width
273
+ * @param int $height
274
+ * @param boolean $crop
275
+ * @param int $quality
276
+ * @return array
277
+ */
278
+ function easingslider_resize_attachment_image($attachmentId, $width, $height, $crop = true, $quality = 100)
279
+ {
280
+ $resizer = new AttachmentImageResizer($attachmentId);
281
+
282
+ return $resizer->resize($width, $height, $crop, $quality);
283
+ }
284
+ }
285
+
286
+ if ( ! function_exists('easingslider_set_attachment_image_urls')) {
287
+ /**
288
+ * Adds the attachment image URL to each slide
289
+ *
290
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
291
+ * @return \EasingSlider\Foundation\Contracts\Models\Model
292
+ */
293
+ function easingslider_set_attachment_image_urls(Model $slider)
294
+ {
295
+ // Continue if using the media library
296
+ if ('media' == $slider->type) {
297
+
298
+ // Copy slides
299
+ $slides = $slider->slides;
300
+
301
+ // Loop through each slide and get attachment URL
302
+ foreach ($slides as &$slide) {
303
+ if ('image' == $slide->type && ! empty($slide->attachment_id)) {
304
+
305
+ // Resize image, if enabled.
306
+ if (true === $slider->image_resizing) {
307
+ $resizedImage = easingslider_resize_attachment_image(
308
+ $slide->attachment_id,
309
+ $slider->width,
310
+ $slider->height
311
+ );
312
+
313
+ $slide->url = $resizedImage['url'];
314
+ } else {
315
+ $attachmentUrl = wp_get_attachment_url($slide->attachment_id, 'full');
316
+
317
+ $slide->url = $attachmentUrl;
318
+ }
319
+ }
320
+ }
321
+
322
+ // Restore slides
323
+ $slider->slides = $slides;
324
+
325
+ }
326
+
327
+ return $slider;
328
+ }
329
+ add_filter('easingslider_pre_display_slider', 'easingslider_set_attachment_image_urls');
330
+ }
331
+
332
+ if ( ! function_exists('easingslider_maybe_randomize_slides')) {
333
+ /**
334
+ * Randomizes the slide order, if enabled.
335
+ *
336
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
337
+ * @return \EasingSlider\Foundation\Contracts\Models\Model
338
+ */
339
+ function easingslider_maybe_randomize_slides(Model $slider)
340
+ {
341
+ // Copy slides
342
+ $slides = $slider->slides;
343
+
344
+ // Randomize if enabled
345
+ if ($slider->randomize) {
346
+ shuffle($slides);
347
+ }
348
+
349
+ // Restore slides
350
+ $slider->slides = $slides;
351
+
352
+ return $slider;
353
+ }
354
+ add_filter('easingslider_pre_display_slider', 'easingslider_maybe_randomize_slides');
355
+ }
356
+
357
+ if ( ! function_exists('easingslider_api_url')) {
358
+ /**
359
+ * Gets the API URL
360
+ *
361
+ * @return string
362
+ */
363
+ function easingslider_api_url()
364
+ {
365
+ return apply_filters('easingslider_api_url', EASINGSLIDER_API_URL);
366
+ }
367
+ }
368
+
369
+ if ( ! function_exists('easingslider_register_addon')) {
370
+ /**
371
+ * Registers an addon
372
+ *
373
+ * @param string $name
374
+ * @param string $file
375
+ * @param string $version
376
+ * @return \EasingSlider\Foundation\Contracts\Admin\PluginUpdaters\PluginUpdater
377
+ */
378
+ function easingslider_register_addon($name, $file, $version)
379
+ {
380
+ if (is_admin()) {
381
+ return Easing_Slider()->make(
382
+ '\EasingSlider\Foundation\Contracts\Admin\PluginUpdaters\PluginUpdater',
383
+ array(
384
+ ':name' => $name,
385
+ ':file' => $file,
386
+ ':version' => $version
387
+ )
388
+ );
389
+ }
390
+ }
391
+ }
392
+
393
+ if ( ! function_exists('easingslider_get_addon_basename')) {
394
+ /**
395
+ * Gets the basename for an addon by the provided slug
396
+ *
397
+ * @param string $slug
398
+ * @return string
399
+ */
400
+ function easingslider_get_addon_basename($slug)
401
+ {
402
+ $keys = array_keys(get_plugins());
403
+
404
+ foreach ($keys as $key) {
405
+ if (preg_match('|^' . $slug . '|', $key)) {
406
+ return $key;
407
+ }
408
+ }
409
+
410
+ return $slug;
411
+ }
412
+ }
413
+
414
+ if ( ! function_exists('easingslider_admin_media_slides_panel')) {
415
+ /**
416
+ * Displays the admin "Media" slides panel
417
+ *
418
+ * @param \EasingSlider\Foundation\Contracts\Models\Model $slider
419
+ * @return void
420
+ */
421
+ function easingslider_admin_media_slides_panel(Model $slider) {
422
+ ?>
423
+ <div class="media-frame wp-core-ui mode-grid hide-menu">
424
+ <div class="media-frame-content" data-columns="5">
425
+ <div id="slides-browser" class="attachments-browser hide-sidebar">
426
+ <?php
427
+ /**
428
+ * Slides are dynamically added using Backbone.js here.
429
+ */
430
+ ?>
431
+ </div>
432
+ </div>
433
+ </div>
434
+ <?php
435
+ }
436
+ add_action('easingslider_admin_media_slides_panel', 'easingslider_admin_media_slides_panel');
437
+ }
438
+
439
+ if ( ! function_exists('easingslider_admin_upgrade_license_response')) {
440
+ /**
441
+ * Tells the user they need to upgrade their license to a new license key.
442
+ * This is a requirements for licenses purchased prior to v3.0.0.
443
+ *
444
+ * @param string $message
445
+ * @param object $data
446
+ * @return string
447
+ */
448
+ function easingslider_admin_upgrade_license_response($message, $data)
449
+ {
450
+ /**
451
+ * If we've gotten an `upgrade_required` response, tell the user.
452
+ * This is a custom one-off response we've created due to circumstances
453
+ * created in major changes to Easing Slider's business model and licensing system.
454
+ */
455
+ if (isset($data->error) && 'upgrade_required' == $data->error) {
456
+
457
+ // Link for upgrading a user's license
458
+ $upgradeLink = 'http://easingslider.com/account/upgrade-license';
459
+
460
+ // Alter the message to tell the user an upgrade is needed
461
+ $message = sprintf(__('An upgrade to your license key is required to allow addon access when using Easing Slider v3.0.0 or greater. <a href="%s" target="_blank">Click here</a> to get your new license key for free.', 'easingslider'), $upgradeLink);
462
+
463
+ }
464
+
465
+ return $message;
466
+ }
467
+ add_filter('easingslider_edd_license_handler_error_response', 'easingslider_admin_upgrade_license_response', 10, 2);
468
+ }
469
+
470
+ if ( ! function_exists('easingslider_admin_upgrade_info_notice')) {
471
+ /**
472
+ * Triggers a notice that is shown to users who have upgraded from v2.* to v3.0.0.
473
+ *
474
+ * @return void
475
+ */
476
+ function easingslider_admin_upgrade_info_notice()
477
+ {
478
+ $hasUpgraded = get_option('easingslider_upgraded_from_v2', false);
479
+
480
+ if ($hasUpgraded) {
481
+ add_action('admin_notices', 'easingslider_admin_show_upgrade_info');
482
+ }
483
+ }
484
+ add_action('admin_init', 'easingslider_admin_upgrade_info_notice');
485
+ }
486
+
487
+ if ( ! function_exists('easingslider_admin_show_upgrade_info')) {
488
+ /**
489
+ * Shows a notice to users who have upgraded.
490
+ *
491
+ * @return void
492
+ */
493
+ function easingslider_admin_show_upgrade_info()
494
+ {
495
+ // Bail if not on one of our admin pages
496
+ if ( ! easingslider_is_admin()) {
497
+ return;
498
+ }
499
+
500
+ ?>
501
+ <div class="message updated upgrade-info">
502
+ <p class="upgrade-info-title"><?php _e('Thanks for Upgrading!', 'easingslider'); ?></p>
503
+ <p class="upgrade-info-text"><?php _e('Thank you for upgrading to Easing Slider v3! So much has changed - please check out the important update information below.', 'easingslider'); ?></p>
504
+ <ul class="upgrade-info-list">
505
+ <li>
506
+ <span class="dashicons dashicons-info"></span>
507
+ <a href="http://easingslider.com/important-changes" target="_blank"><?php _e('Important Addon & Licensing Changes', 'easingslider'); ?></a>
508
+ </li>
509
+ <li>
510
+ <span class="dashicons dashicons-dismiss"></span>
511
+ <a href="<?php echo esc_attr(add_query_arg('easingslider_action', 'dismiss_upgrade_info')); ?>"><?php _e('Dismiss', 'easingslider'); ?></a>
512
+ </li>
513
+ </ul>
514
+ </div>
515
+ <?php
516
+ }
517
+ }
518
+
519
+ if ( ! function_exists('easingslider_admin_dismiss_upgrade_info')) {
520
+ /**
521
+ * Dismisses the upgrade info notice
522
+ *
523
+ * @return void
524
+ */
525
+ function easingslider_admin_dismiss_upgrade_info()
526
+ {
527
+ delete_option('easingslider_upgraded_from_v2');
528
+ }
529
+ add_action('easingslider_dismiss_upgrade_info', 'easingslider_admin_dismiss_upgrade_info');
530
+ }
templates/slider.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php easingslider_inline_styles($slider); ?>
2
+
3
+ <?php easingslider_inline_script($slider); ?>
4
+
5
+ <div data-id="<?php echo esc_attr($slider->ID); ?>" <?php easingslider_container_classes($slider); ?>>
6
+ <?php foreach ($slider->slides as $slide) : ?>
7
+ <div class="easingslider-slide">
8
+ <?php easingslider_display_slide($slide, $slider); ?>
9
+ </div>
10
+ <?php endforeach; ?>
11
+ </div>
uninstall.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( ! defined('WP_UNINSTALL_PLUGIN')) {
5
+ exit;
6
+ }
7
+
8
+ // Load Easing Slider file
9
+ include_once('easing-slider.php');
10
+
11
+ // Get plugin instance
12
+ $plugin = Easing_Slider();
13
+
14
+ // Get settings
15
+ $settings = $plugin->settings();
16
+
17
+ // Run removal, if enabled by the user.
18
+ if (true === $settings['remove_data']) {
19
+ $uninstaller = $plugin->uninstaller();
20
+ $uninstaller->uninstall();
21
+ }
vendor/autoload.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload.php @generated by Composer
4
+
5
+ require_once __DIR__ . '/composer' . '/autoload_real.php';
6
+
7
+ return ComposerAutoloaderInitb0e525be76a617dacdcfc82a350d6a9f::getLoader();
vendor/composer/ClassLoader.php ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Autoload;
14
+
15
+ /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17
+ *
18
+ * $loader = new \Composer\Autoload\ClassLoader();
19
+ *
20
+ * // register classes with namespaces
21
+ * $loader->add('Symfony\Component', __DIR__.'/component');
22
+ * $loader->add('Symfony', __DIR__.'/framework');
23
+ *
24
+ * // activate the autoloader
25
+ * $loader->register();
26
+ *
27
+ * // to enable searching the include path (eg. for PEAR packages)
28
+ * $loader->setUseIncludePath(true);
29
+ *
30
+ * In this example, if you try to use a class in the Symfony\Component
31
+ * namespace or one of its children (Symfony\Component\Console for instance),
32
+ * the autoloader will first look for the class under the component/
33
+ * directory, and it will then fallback to the framework/ directory if not
34
+ * found before giving up.
35
+ *
36
+ * This class is loosely based on the Symfony UniversalClassLoader.
37
+ *
38
+ * @author Fabien Potencier <fabien@symfony.com>
39
+ * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
+ */
43
+ class ClassLoader
44
+ {
45
+ // PSR-4
46
+ private $prefixLengthsPsr4 = array();
47
+ private $prefixDirsPsr4 = array();
48
+ private $fallbackDirsPsr4 = array();
49
+
50
+ // PSR-0
51
+ private $prefixesPsr0 = array();
52
+ private $fallbackDirsPsr0 = array();
53
+
54
+ private $useIncludePath = false;
55
+ private $classMap = array();
56
+
57
+ private $classMapAuthoritative = false;
58
+
59
+ public function getPrefixes()
60
+ {
61
+ if (!empty($this->prefixesPsr0)) {
62
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
63
+ }
64
+
65
+ return array();
66
+ }
67
+
68
+ public function getPrefixesPsr4()
69
+ {
70
+ return $this->prefixDirsPsr4;
71
+ }
72
+
73
+ public function getFallbackDirs()
74
+ {
75
+ return $this->fallbackDirsPsr0;
76
+ }
77
+
78
+ public function getFallbackDirsPsr4()
79
+ {
80
+ return $this->fallbackDirsPsr4;
81
+ }
82
+
83
+ public function getClassMap()
84
+ {
85
+ return $this->classMap;
86
+ }
87
+
88
+ /**
89
+ * @param array $classMap Class to filename map
90
+ */
91
+ public function addClassMap(array $classMap)
92
+ {
93
+ if ($this->classMap) {
94
+ $this->classMap = array_merge($this->classMap, $classMap);
95
+ } else {
96
+ $this->classMap = $classMap;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Registers a set of PSR-0 directories for a given prefix, either
102
+ * appending or prepending to the ones previously set for this prefix.
103
+ *
104
+ * @param string $prefix The prefix
105
+ * @param array|string $paths The PSR-0 root directories
106
+ * @param bool $prepend Whether to prepend the directories
107
+ */
108
+ public function add($prefix, $paths, $prepend = false)
109
+ {
110
+ if (!$prefix) {
111
+ if ($prepend) {
112
+ $this->fallbackDirsPsr0 = array_merge(
113
+ (array) $paths,
114
+ $this->fallbackDirsPsr0
115
+ );
116
+ } else {
117
+ $this->fallbackDirsPsr0 = array_merge(
118
+ $this->fallbackDirsPsr0,
119
+ (array) $paths
120
+ );
121
+ }
122
+
123
+ return;
124
+ }
125
+
126
+ $first = $prefix[0];
127
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
128
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
129
+
130
+ return;
131
+ }
132
+ if ($prepend) {
133
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
134
+ (array) $paths,
135
+ $this->prefixesPsr0[$first][$prefix]
136
+ );
137
+ } else {
138
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
139
+ $this->prefixesPsr0[$first][$prefix],
140
+ (array) $paths
141
+ );
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Registers a set of PSR-4 directories for a given namespace, either
147
+ * appending or prepending to the ones previously set for this namespace.
148
+ *
149
+ * @param string $prefix The prefix/namespace, with trailing '\\'
150
+ * @param array|string $paths The PSR-4 base directories
151
+ * @param bool $prepend Whether to prepend the directories
152
+ *
153
+ * @throws \InvalidArgumentException
154
+ */
155
+ public function addPsr4($prefix, $paths, $prepend = false)
156
+ {
157
+ if (!$prefix) {
158
+ // Register directories for the root namespace.
159
+ if ($prepend) {
160
+ $this->fallbackDirsPsr4 = array_merge(
161
+ (array) $paths,
162
+ $this->fallbackDirsPsr4
163
+ );
164
+ } else {
165
+ $this->fallbackDirsPsr4 = array_merge(
166
+ $this->fallbackDirsPsr4,
167
+ (array) $paths
168
+ );
169
+ }
170
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
171
+ // Register directories for a new namespace.
172
+ $length = strlen($prefix);
173
+ if ('\\' !== $prefix[$length - 1]) {
174
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
175
+ }
176
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
177
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
178
+ } elseif ($prepend) {
179
+ // Prepend directories for an already registered namespace.
180
+ $this->prefixDirsPsr4[$prefix] = array_merge(
181
+ (array) $paths,
182
+ $this->prefixDirsPsr4[$prefix]
183
+ );
184
+ } else {
185
+ // Append directories for an already registered namespace.
186
+ $this->prefixDirsPsr4[$prefix] = array_merge(
187
+ $this->prefixDirsPsr4[$prefix],
188
+ (array) $paths
189
+ );
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Registers a set of PSR-0 directories for a given prefix,
195
+ * replacing any others previously set for this prefix.
196
+ *
197
+ * @param string $prefix The prefix
198
+ * @param array|string $paths The PSR-0 base directories
199
+ */
200
+ public function set($prefix, $paths)
201
+ {
202
+ if (!$prefix) {
203
+ $this->fallbackDirsPsr0 = (array) $paths;
204
+ } else {
205
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Registers a set of PSR-4 directories for a given namespace,
211
+ * replacing any others previously set for this namespace.
212
+ *
213
+ * @param string $prefix The prefix/namespace, with trailing '\\'
214
+ * @param array|string $paths The PSR-4 base directories
215
+ *
216
+ * @throws \InvalidArgumentException
217
+ */
218
+ public function setPsr4($prefix, $paths)
219
+ {
220
+ if (!$prefix) {
221
+ $this->fallbackDirsPsr4 = (array) $paths;
222
+ } else {
223
+ $length = strlen($prefix);
224
+ if ('\\' !== $prefix[$length - 1]) {
225
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
226
+ }
227
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
228
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Turns on searching the include path for class files.
234
+ *
235
+ * @param bool $useIncludePath
236
+ */
237
+ public function setUseIncludePath($useIncludePath)
238
+ {
239
+ $this->useIncludePath = $useIncludePath;
240
+ }
241
+
242
+ /**
243
+ * Can be used to check if the autoloader uses the include path to check
244
+ * for classes.
245
+ *
246
+ * @return bool
247
+ */
248
+ public function getUseIncludePath()
249
+ {
250
+ return $this->useIncludePath;
251
+ }
252
+
253
+ /**
254
+ * Turns off searching the prefix and fallback directories for classes
255
+ * that have not been registered with the class map.
256
+ *
257
+ * @param bool $classMapAuthoritative
258
+ */
259
+ public function setClassMapAuthoritative($classMapAuthoritative)
260
+ {
261
+ $this->classMapAuthoritative = $classMapAuthoritative;
262
+ }
263
+
264
+ /**
265
+ * Should class lookup fail if not found in the current class map?
266
+ *
267
+ * @return bool
268
+ */
269
+ public function isClassMapAuthoritative()
270
+ {
271
+ return $this->classMapAuthoritative;
272
+ }
273
+
274
+ /**
275
+ * Registers this instance as an autoloader.
276
+ *
277
+ * @param bool $prepend Whether to prepend the autoloader or not
278
+ */
279
+ public function register($prepend = false)
280
+ {
281
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
282
+ }
283
+
284
+ /**
285
+ * Unregisters this instance as an autoloader.
286
+ */
287
+ public function unregister()
288
+ {
289
+ spl_autoload_unregister(array($this, 'loadClass'));
290
+ }
291
+
292
+ /**
293
+ * Loads the given class or interface.
294
+ *
295
+ * @param string $class The name of the class
296
+ * @return bool|null True if loaded, null otherwise
297
+ */
298
+ public function loadClass($class)
299
+ {
300
+ if ($file = $this->findFile($class)) {
301
+ includeFile($file);
302
+
303
+ return true;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Finds the path to the file where the class is defined.
309
+ *
310
+ * @param string $class The name of the class
311
+ *
312
+ * @return string|false The path if found, false otherwise
313
+ */
314
+ public function findFile($class)
315
+ {
316
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
+ if ('\\' == $class[0]) {
318
+ $class = substr($class, 1);
319
+ }
320
+
321
+ // class map lookup
322
+ if (isset($this->classMap[$class])) {
323
+ return $this->classMap[$class];
324
+ }
325
+ if ($this->classMapAuthoritative) {
326
+ return false;
327
+ }
328
+
329
+ $file = $this->findFileWithExtension($class, '.php');
330
+
331
+ // Search for Hack files if we are running on HHVM
332
+ if ($file === null && defined('HHVM_VERSION')) {
333
+ $file = $this->findFileWithExtension($class, '.hh');
334
+ }
335
+
336
+ if ($file === null) {
337
+ // Remember that this class does not exist.
338
+ return $this->classMap[$class] = false;
339
+ }
340
+
341
+ return $file;
342
+ }
343
+
344
+ private function findFileWithExtension($class, $ext)
345
+ {
346
+ // PSR-4 lookup
347
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
348
+
349
+ $first = $class[0];
350
+ if (isset($this->prefixLengthsPsr4[$first])) {
351
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
+ if (0 === strpos($class, $prefix)) {
353
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
355
+ return $file;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+
362
+ // PSR-4 fallback dirs
363
+ foreach ($this->fallbackDirsPsr4 as $dir) {
364
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365
+ return $file;
366
+ }
367
+ }
368
+
369
+ // PSR-0 lookup
370
+ if (false !== $pos = strrpos($class, '\\')) {
371
+ // namespaced class name
372
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
373
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
374
+ } else {
375
+ // PEAR-like class name
376
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
377
+ }
378
+
379
+ if (isset($this->prefixesPsr0[$first])) {
380
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381
+ if (0 === strpos($class, $prefix)) {
382
+ foreach ($dirs as $dir) {
383
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384
+ return $file;
385
+ }
386
+ }
387
+ }
388
+ }
389
+ }
390
+
391
+ // PSR-0 fallback dirs
392
+ foreach ($this->fallbackDirsPsr0 as $dir) {
393
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394
+ return $file;
395
+ }
396
+ }
397
+
398
+ // PSR-0 include paths.
399
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400
+ return $file;
401
+ }
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Scope isolated include.
407
+ *
408
+ * Prevents access to $this/self from included files.
409
+ */
410
+ function includeFile($file)
411
+ {
412
+ include $file;
413
+ }
vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) 2015 Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
vendor/composer/autoload_classmap.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_classmap.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ );
vendor/composer/autoload_files.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_files.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'aeb63d164f6cca31ad3c0b587e63813b' => $baseDir . '/src/Foundation/helpers.php',
10
+ '8820040b8131984b49e14e759290eb43' => $baseDir . '/src/Plugin/helpers.php',
11
+ );
vendor/composer/autoload_namespaces.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_namespaces.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src'),
10
+ );
vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_psr4.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'EasingSlider\\' => array($baseDir . '/src'),
10
+ 'Auryn\\' => array($vendorDir . '/rdlowrey/auryn/lib'),
11
+ );
vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInitb0e525be76a617dacdcfc82a350d6a9f
6
+ {
7
+ private static $loader;
8
+
9
+ public static function loadClassLoader($class)
10
+ {
11
+ if ('Composer\Autoload\ClassLoader' === $class) {
12
+ require __DIR__ . '/ClassLoader.php';
13
+ }
14
+ }
15
+
16
+ public static function getLoader()
17
+ {
18
+ if (null !== self::$loader) {
19
+ return self::$loader;
20
+ }
21
+
22
+ spl_autoload_register(array('ComposerAutoloaderInitb0e525be76a617dacdcfc82a350d6a9f', 'loadClassLoader'), true, true);
23
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitb0e525be76a617dacdcfc82a350d6a9f', 'loadClassLoader'));
25
+
26
+ $map = require __DIR__ . '/autoload_namespaces.php';
27
+ foreach ($map as $namespace => $path) {
28
+ $loader->set($namespace, $path);
29
+ }
30
+
31
+ $map = require __DIR__ . '/autoload_psr4.php';
32
+ foreach ($map as $namespace => $path) {
33
+ $loader->setPsr4($namespace, $path);
34
+ }
35
+
36
+ $classMap = require __DIR__ . '/autoload_classmap.php';
37
+ if ($classMap) {
38
+ $loader->addClassMap($classMap);
39
+ }
40
+
41
+ $loader->register(true);
42
+
43
+ $includeFiles = require __DIR__ . '/autoload_files.php';
44
+ foreach ($includeFiles as $fileIdentifier => $file) {
45
+ composerRequireb0e525be76a617dacdcfc82a350d6a9f($fileIdentifier, $file);
46
+ }
47
+
48
+ return $loader;
49
+ }
50
+ }
51
+
52
+ function composerRequireb0e525be76a617dacdcfc82a350d6a9f($fileIdentifier, $file)
53
+ {
54
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
55
+ require $file;
56
+
57
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
58
+ }
59
+ }
vendor/composer/installed.json ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "composer/installers",
4
+ "version": "dev-master",
5
+ "version_normalized": "9999999-dev",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/composer/installers.git",
9
+ "reference": "6aac6a0a931ad06780fa7c574f27178d48109ec7"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/composer/installers/zipball/21a8c06dd5fe0a22b776797cc552e51d17d7e7dd",
14
+ "reference": "6aac6a0a931ad06780fa7c574f27178d48109ec7",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "composer-plugin-api": "^1.0"
19
+ },
20
+ "replace": {
21
+ "roundcube/plugin-installer": "*",
22
+ "shama/baton": "*"
23
+ },
24
+ "require-dev": {
25
+ "composer/composer": "1.0.*@dev",
26
+ "phpunit/phpunit": "4.1.*"
27
+ },
28
+ "time": "2016-03-23 16:25:33",
29
+ "type": "composer-plugin",
30
+ "extra": {
31
+ "class": "Composer\\Installers\\Plugin",
32
+ "branch-alias": {
33
+ "dev-master": "1.0-dev"
34
+ }
35
+ },
36
+ "installation-source": "source",
37
+ "autoload": {
38
+ "psr-0": {
39
+ "Composer\\Installers\\": "src/"
40
+ }
41
+ },
42
+ "notification-url": "https://packagist.org/downloads/",
43
+ "license": [
44
+ "MIT"
45
+ ],
46
+ "authors": [
47
+ {
48
+ "name": "Kyle Robinson Young",
49
+ "email": "kyle@dontkry.com",
50
+ "homepage": "https://github.com/shama"
51
+ }
52
+ ],
53
+ "description": "A multi-framework Composer library installer",
54
+ "homepage": "https://composer.github.io/installers/",
55
+ "keywords": [
56
+ "Craft",
57
+ "Dolibarr",
58
+ "Hurad",
59
+ "MODX Evo",
60
+ "Mautic",
61
+ "OXID",
62
+ "SMF",
63
+ "Thelia",
64
+ "WolfCMS",
65
+ "agl",
66
+ "aimeos",
67
+ "annotatecms",
68
+ "bitrix",
69
+ "cakephp",
70
+ "chef",
71
+ "codeigniter",
72
+ "concrete5",
73
+ "croogo",
74
+ "dokuwiki",
75
+ "drupal",
76
+ "elgg",
77
+ "fuelphp",
78
+ "grav",
79
+ "installer",
80
+ "joomla",
81
+ "kohana",
82
+ "laravel",
83
+ "lithium",
84
+ "magento",
85
+ "mako",
86
+ "mediawiki",
87
+ "modulework",
88
+ "moodle",
89
+ "phpbb",
90
+ "piwik",
91
+ "ppi",
92
+ "puppet",
93
+ "roundcube",
94
+ "shopware",
95
+ "silverstripe",
96
+ "symfony",
97
+ "typo3",
98
+ "wordpress",
99
+ "zend",
100
+ "zikula"
101
+ ]
102
+ },
103
+ {
104
+ "name": "rdlowrey/auryn",
105
+ "version": "v1.4.0",
106
+ "version_normalized": "1.4.0.0",
107
+ "source": {
108
+ "type": "git",
109
+ "url": "https://github.com/rdlowrey/auryn.git",
110
+ "reference": "2e4240791162dfe073d59654d8dc06df0eb0b73f"
111
+ },
112
+ "dist": {
113
+ "type": "zip",
114
+ "url": "https://api.github.com/repos/rdlowrey/auryn/zipball/2e4240791162dfe073d59654d8dc06df0eb0b73f",
115
+ "reference": "2e4240791162dfe073d59654d8dc06df0eb0b73f",
116
+ "shasum": ""
117
+ },
118
+ "require": {
119
+ "php": ">=5.3.0"
120
+ },
121
+ "require-dev": {
122
+ "athletic/athletic": "~0.1",
123
+ "fabpot/php-cs-fixer": "~1.9",
124
+ "phpunit/phpunit": "^4.7"
125
+ },
126
+ "time": "2016-03-14 20:10:19",
127
+ "type": "library",
128
+ "installation-source": "dist",
129
+ "autoload": {
130
+ "psr-4": {
131
+ "Auryn\\": "lib/"
132
+ }
133
+ },
134
+ "notification-url": "https://packagist.org/downloads/",
135
+ "license": [
136
+ "MIT"
137
+ ],
138
+ "authors": [
139
+ {
140
+ "name": "Dan Ackroyd",
141
+ "email": "Danack@basereality.com",
142
+ "homepage": "http://www.basereality.com",
143
+ "role": "Developer"
144
+ },
145
+ {
146
+ "name": "Levi Morrison",
147
+ "email": "levim@php.net",
148
+ "homepage": "http://morrisonlevi.github.com/",
149
+ "role": "Developer"
150
+ },
151
+ {
152
+ "name": "Daniel Lowrey",
153
+ "email": "rdlowrey@gmail.com",
154
+ "homepage": "https://github.com/rdlowrey",
155
+ "role": "Creator / Main Developer"
156
+ }
157
+ ],
158
+ "description": "Auryn is a dependency injector for bootstrapping object-oriented PHP applications.",
159
+ "homepage": "https://github.com/rdlowrey/auryn",
160
+ "keywords": [
161
+ "dependency injection",
162
+ "dic",
163
+ "ioc"
164
+ ]
165
+ }
166
+ ]
vendor/rdlowrey/auryn/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ vendor/
2
+ composer.lock
3
+ .idea
vendor/rdlowrey/auryn/.php_cs ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ return Symfony\CS\Config\Config::create()
4
+ ->level(Symfony\CS\FixerInterface::NONE_LEVEL)
5
+ ->fixers([
6
+ "-psr0",
7
+ "psr2",
8
+ "psr4",
9
+ ])
10
+ ->finder(
11
+ Symfony\CS\Finder\DefaultFinder::create()
12
+ ->in(__DIR__ . "/lib")
13
+ ->in(__DIR__ . "/test")
14
+ )
15
+ ;
vendor/rdlowrey/auryn/.travis.yml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+ php:
3
+ - 5.3
4
+ - 5.4
5
+ - 5.5
6
+ - 5.6
7
+ - 7.0
8
+ - hhvm
9
+ before_script:
10
+ - composer install
11
+ sudo: false
12
+ script:
13
+ - phpunit
14
+ - vendor/bin/athletic --path test/Benchmark --formatter GroupedFormatter
vendor/rdlowrey/auryn/CONTRIBUTING.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Submitting useful bug reports
2
+
3
+ Please search existing issues first to make sure this is not a duplicate.
4
+ Every issue report has a cost for the developers required to field it; be
5
+ respectful of others' time and ensure your report isn't spurious prior to
6
+ submission. Additionally, please do us all a favor by adhering to the
7
+ principles of sound bug reporting laid out by Simon Tatham here:
8
+
9
+ http://www.chiark.greenend.org.uk/~sgtatham/bugs.html
10
+
11
+ ## Development ideology
12
+
13
+ Truths which we believe to be self-evident:
14
+
15
+ - **The answer is not more options.** If you feel compelled to expose
16
+ new preferences to the user it's very possible you've made a wrong
17
+ turn somewhere.
18
+
19
+ - **There are no power users.** The idea that some users "understand"
20
+ concepts better than others has proven to be, for the most part, false.
21
+ If anything, "power users" are more dangerous than the rest, and we
22
+ should avoid exposing dangerous functionality to them.
23
+
24
+ ## Code style
25
+
26
+ Please ensure any submissions adhere to the PSR-2 code style standard:
27
+
28
+ https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
vendor/rdlowrey/auryn/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013-2014 Daniel Lowrey, Levi Morrison, Dan Ackroyd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a
6
+ copy of this software and associated documentation files (the "Software"),
7
+ to deal in the Software without restriction, including without limitation
8
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
+ and/or sell copies of the Software, and to permit persons to whom the
10
+ Software is furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included
13
+ in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ IN THE SOFTWARE.
vendor/rdlowrey/auryn/README.md ADDED
@@ -0,0 +1,847 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # auryn [![Build Status](https://travis-ci.org/rdlowrey/auryn.svg?branch=master)](https://travis-ci.org/rdlowrey/auryn)
2
+
3
+ auryn is a recursive dependency injector. Use auryn to bootstrap and wire together
4
+ S.O.L.I.D., object-oriented PHP applications.
5
+
6
+ ##### How It Works
7
+
8
+ Among other things, auryn recursively instantiates class dependencies based on the parameter
9
+ type-hints specified in class constructor signatures. This requires the use of Reflection. You may
10
+ have heard that "reflection is slow". Let's clear something up: *anything* can be "slow" if you're
11
+ doing it wrong. Reflection is an order of magnitude faster than disk access and several orders of
12
+ magnitude faster than retrieving information (for example) from a remote database. Additionally,
13
+ each reflection offers the opportunity to cache the results if you're worried about speed. auryn
14
+ caches any reflections it generates to minimize the potential performance impact.
15
+
16
+ > auryn **is NOT** a Service Locator. DO NOT turn it into one by passing the injector into your
17
+ > application classes. Service Locator is an anti-pattern; it hides class dependencies, makes code
18
+ > more difficult to maintain and makes a liar of your API! You should *only* use an injector for
19
+ > wiring together the disparate parts of your application during your bootstrap phase.
20
+
21
+ ## The Guide
22
+
23
+ **Basic Usage**
24
+
25
+ * [Basic Instantiation](#basic-instantiation)
26
+ * [Injection Definitions](#injection-definitions)
27
+ * [Type-Hint Aliasing](#type-hint-aliasing)
28
+ * [Non-Class Parameters](#non-class-parameters)
29
+ * [Global Parameter Definitions](#global-parameter-definitions)
30
+
31
+ **Advanced Usage**
32
+
33
+ * [Instance Sharing](#instance-sharing)
34
+ * [Instantiation Delegates](#instantiation-delegates)
35
+ * [Prepares and Setter Injection](#prepares-and-setter-injection)
36
+ * [Injecting for Execution](#injecting-for-execution)
37
+ * [Dependency Resolution](#dependency-resolution)
38
+
39
+ **Example Use Cases**
40
+
41
+ * [Avoiding Evil Singletons](#avoiding-evil-singletons)
42
+ * [Application Bootstrapping](#app-bootstrapping)
43
+
44
+
45
+ ## Requirements and Installation
46
+
47
+ - auryn requires PHP 5.3 or higher.
48
+
49
+ #### Installation
50
+
51
+ ###### Github
52
+
53
+ You can clone the latest auryn iteration at anytime from the github repository:
54
+
55
+ ```bash
56
+ $ git clone git://github.com/rdlowrey/auryn.git
57
+ ```
58
+
59
+ ###### Composer
60
+
61
+ You may also use composer to include auryn as a dependency in your projects `composer.json`. The relevant package is `rdlowrey/auryn`.
62
+
63
+ Alternatively require the package using composer cli:
64
+
65
+ ```bash
66
+ composer require rdlowrey/auryn
67
+ ```
68
+
69
+ ##### Manual Download
70
+
71
+ Archived tagged release versions are also available for manual download on the project
72
+ [tags page](https://github.com/rdlowrey/auryn/tags)
73
+
74
+
75
+ ## Basic Usage
76
+
77
+ To start using the injector, simply create a new instance of the `Auryn\Injector` ("the Injector")
78
+ class:
79
+
80
+ ```php
81
+ <?php
82
+ $injector = new Auryn\Injector;
83
+ ```
84
+
85
+ ### Basic Instantiation
86
+
87
+ If a class doesn't specify any dependencies in its constructor signature there's little point in
88
+ using the Injector to generate it. However, for the sake of completeness consider that you can do
89
+ the following with equivalent results:
90
+
91
+ ```php
92
+ <?php
93
+ $injector = new Auryn\Injector;
94
+ $obj1 = new SomeNamespace\MyClass;
95
+ $obj2 = $injector->make('SomeNamespace\MyClass');
96
+
97
+ var_dump($obj2 instanceof SomeNamespace\MyClass); // true
98
+ ```
99
+
100
+ ###### Concrete Type-hinted Dependencies
101
+
102
+ If a class only asks for concrete dependencies you can use the Injector to inject them without
103
+ specifying any injection definitions. For example, in the following scenario you can use the
104
+ Injector to automatically provision `MyClass` with the required `SomeDependency` and `AnotherDependency`
105
+ class instances:
106
+
107
+ ```php
108
+ <?php
109
+ class SomeDependency {}
110
+
111
+ class AnotherDependency {}
112
+
113
+ class MyClass {
114
+ public $dep1;
115
+ public $dep2;
116
+ public function __construct(SomeDependency $dep1, AnotherDependency $dep2) {
117
+ $this->dep1 = $dep1;
118
+ $this->dep2 = $dep2;
119
+ }
120
+ }
121
+
122
+ $injector = new Auryn\Injector;
123
+ $myObj = $injector->make('MyClass');
124
+
125
+ var_dump($myObj->dep1 instanceof SomeDependency); // true
126
+ var_dump($myObj->dep2 instanceof AnotherDependency); // true
127
+ ```
128
+
129
+ ###### Recursive Dependency Instantiation
130
+
131
+ One of the Injector's key attributes is that it recursively traverses class dependency trees to
132
+ instantiate objects. This is just a fancy way of saying, "if you instantiate object A which asks for
133
+ object B, the Injector will instantiate any of object B's dependencies so that B can be instantiated
134
+ and provided to A". This is perhaps best understood with a simple example. Consider the following
135
+ classes in which a `Car` asks for `Engine` and the `Engine` class has concrete dependencies of its
136
+ own:
137
+
138
+ ```php
139
+ <?php
140
+ class Car {
141
+ private $engine;
142
+ public function __construct(Engine $engine) {
143
+ $this->engine = $engine;
144
+ }
145
+ }
146
+
147
+ class Engine {
148
+ private $sparkPlug;
149
+ private $piston;
150
+ public function __construct(SparkPlug $sparkPlug, Piston $piston) {
151
+ $this->sparkPlug = $sparkPlug;
152
+ $this->piston = $piston;
153
+ }
154
+ }
155
+
156
+ $injector = new Auryn\Injector;
157
+ $car = $injector->make('Car');
158
+ var_dump($car instanceof Car); // true
159
+ ```
160
+
161
+ ### Injection Definitions
162
+
163
+ You may have noticed that the previous examples all demonstrated instantiation of classes with
164
+ explicit, type-hinted, concrete constructor parameters. Obviously, many of your classes won't fit
165
+ this mold. Some classes will type-hint interfaces and abstract classes. Some will specify scalar
166
+ parameters which offer no possibility of type-hinting in PHP. Still other parameters will be arrays,
167
+ etc. In such cases we need to assist the Injector by telling it exactly what we want to inject.
168
+
169
+ ###### Defining Class Names for Constructor Parameters
170
+
171
+ Let's look at how to provision a class with non-concrete type-hints in its constructor signature.
172
+ Consider the following code in which a `Car` needs an `Engine` and `Engine` is an interface:
173
+
174
+ ```php
175
+ <?php
176
+ interface Engine {}
177
+
178
+ class V8 implements Engine {}
179
+
180
+ class Car {
181
+ private $engine;
182
+ public function __construct(Engine $engine) {
183
+ $this->engine = $engine;
184
+ }
185
+ }
186
+ ```
187
+
188
+ To instantiate a `Car` in this case, we simply need to define an injection definition for the class
189
+ ahead of time:
190
+
191
+ ```php
192
+ <?php
193
+ $injector = new Auryn\Injector;
194
+ $injector->define('Car', ['engine' => 'V8']);
195
+ $car = $injector->make('Car');
196
+
197
+ var_dump($car instanceof Car); // true
198
+ ```
199
+
200
+ The most important points to notice here are:
201
+
202
+ 1. A custom definition is an `array` whose keys match constructor parameter names
203
+ 2. The values in the definition array represent the class names to inject for the specified
204
+ parameter key
205
+
206
+ Because the `Car` constructor parameter we needed to define was named `$engine`, our definition
207
+ specified an `engine` key whose value was the name of the class (`V8`) that we want to inject.
208
+
209
+ Custom injection definitions are only necessary on a per-parameter basis. For example, in the
210
+ following class we only need to define the injectable class for `$arg2` because `$arg1` specifies a
211
+ concrete class type-hint:
212
+
213
+ ```php
214
+ <?php
215
+ class MyClass {
216
+ private $arg1;
217
+ private $arg2;
218
+ public function __construct(SomeConcreteClass $arg1, SomeInterface $arg2) {
219
+ $this->arg1 = $arg1;
220
+ $this->arg2 = $arg2;
221
+ }
222
+ }
223
+
224
+ $injector = new Auryn\Injector;
225
+ $injector->define('MyClass', ['arg2' => 'SomeImplementationClass']);
226
+
227
+ $myObj = $injector->make('MyClass');
228
+ ```
229
+
230
+ > **NOTE:** Injecting instances where an abstract class is type-hinted works in exactly the same way
231
+ as the above examples for interface type-hints.
232
+
233
+ ###### Using Existing Instances in Injection Definitions
234
+
235
+ Injection definitions may also specify a pre-existing instance of the requisite class instead of the
236
+ string class name:
237
+
238
+ ```php
239
+ <?php
240
+ interface SomeInterface {}
241
+
242
+ class SomeImplementation implements SomeInterface {}
243
+
244
+ class MyClass {
245
+ private $dependency;
246
+ public function __construct(SomeInterface $dependency) {
247
+ $this->dependency = $dependency;
248
+ }
249
+ }
250
+
251
+ $injector = new Auryn\Injector;
252
+ $dependencyInstance = new SomeImplementation;
253
+ $injector->define('MyClass', [':dependency' => $dependencyInstance]);
254
+
255
+ $myObj = $injector->make('MyClass');
256
+
257
+ var_dump($myObj instanceof MyClass); // true
258
+ ```
259
+
260
+ > **NOTE:** Since this `define()` call is passing raw values (as evidenced by the colon `:` usage),
261
+ you can achieve the same result by omitting the array key(s) and relying on parameter order rather
262
+ than name. Like so: `$injector->define('MyClass', [$dependencyInstance]);`
263
+
264
+ ###### Specifying Injection Definitions On the Fly
265
+
266
+ You may also specify injection definitions at call-time with `Auryn\Injector::make`. Consider:
267
+
268
+ ```php
269
+ <?php
270
+ interface SomeInterface {}
271
+
272
+ class SomeImplementationClass implements SomeInterface {}
273
+
274
+ class MyClass {
275
+ private $dependency;
276
+ public function __construct(SomeInterface $dependency) {
277
+ $this->dependency = $dependency;
278
+ }
279
+ }
280
+
281
+ $injector = new Auryn\Injector;
282
+ $myObj = $injector->make('MyClass', ['dependency' => 'SomeImplementation']);
283
+
284
+ var_dump($myObj instanceof MyClass); // true
285
+ ```
286
+
287
+ The above code shows how even though we haven't called the Injector's `define` method, the
288
+ call-time specification allows us to instantiate `MyClass`.
289
+
290
+ > **NOTE:** on-the-fly instantiation definitions will override a pre-defined definition for the
291
+ specified class, but only in the context of that particular call to `Auryn\Injector::make`.
292
+
293
+ ### Type-Hint Aliasing
294
+
295
+ Programming to interfaces is one of the most useful concepts in object-oriented design (OOD), and
296
+ well-designed code should type-hint interfaces whenever possible. But does this mean we have to
297
+ assign injection definitions for every class in our application to reap the benefits of abstracted
298
+ dependencies? Thankfully the answer to this question is, "NO." The Injector accommodates this goal
299
+ by accepting "aliases". Consider:
300
+
301
+ ```php
302
+ <?php
303
+ interface Engine {}
304
+ class V8 implements Engine {}
305
+ class Car {
306
+ private $engine;
307
+ public function __construct(Engine $engine) {
308
+ $this->engine = $engine;
309
+ }
310
+ }
311
+
312
+ $injector = new Auryn\Injector;
313
+
314
+ // Tell the Injector class to inject an instance of V8 any time
315
+ // it encounters an Engine type-hint
316
+ $injector->alias('Engine', 'V8');
317
+
318
+ $car = $injector->make('Car');
319
+ var_dump($car instanceof Car); // bool(true)
320
+ ```
321
+
322
+ In this example we've demonstrated how to specify an alias class for any occurrence of a particular
323
+ interface or abstract class type-hint. Once an implementation is assigned, the Injector will use it
324
+ to provision any parameter with a matching type-hint.
325
+
326
+ > **IMPORTANT:** If an injection definition is defined for a parameter covered by an implementation
327
+ assignment, the definition takes precedence over the implementation.
328
+
329
+ ### Non-Class Parameters
330
+
331
+ All of the previous examples have demonstrated how the Injector class instantiates parameters based
332
+ on type-hints, class name definitions and existing instances. But what happens if we want to inject
333
+ a scalar or other non-object variable into a class? First, let's establish the following behavioral
334
+ rule:
335
+
336
+ > **IMPORTANT:** The Injector assumes all named-parameter definitions are class names by default.
337
+
338
+ If you want the Injector to treat a named-parameter definition as a "raw" value and not a class name,
339
+ you must prefix the parameter name in your definition with a colon character `:`. For example,
340
+ consider the following code in which we tell the Injector to share a `PDO` database connection
341
+ instance and define its scalar constructor parameters:
342
+
343
+ ```php
344
+ <?php
345
+ $injector = new Auryn\Injector;
346
+ $injector->share('PDO');
347
+ $injector->define('PDO', [
348
+ ':dsn' => 'mysql:dbname=testdb;host=127.0.0.1',
349
+ ':username' => 'dbuser',
350
+ ':passwd' => 'dbpass'
351
+ ]);
352
+
353
+ $db = $injector->make('PDO');
354
+ ```
355
+
356
+ The colon character preceding the parameter names tells the Injector that the associated values ARE
357
+ NOT class names. If the colons had been omitted above, auryn would attempt to instantiate classes of
358
+ the names specified in the string and an exception would result. Also, note that we could just as
359
+ easily specified arrays or integers or any other data type in the above definitions. As long as the
360
+ parameter name is prefixed with a `:`, auryn will inject the value directly without attempting to
361
+ instantiate it.
362
+
363
+ > **NOTE:** As mentioned previously, since this `define()` call is passing raw values, you may opt to
364
+ assign the values by parameter order rather than name. Since PDO's first three parameters are `$dsn`,
365
+ `$username`, and `$password`, in that order, you could accomplish the same result by leaving out the
366
+ array keys, like so:
367
+ `$injector->define('PDO', ['mysql:dbname=testdb;host=127.0.0.1', 'dbuser', 'dbpass']);`
368
+
369
+ ### Global Parameter Definitions
370
+
371
+ Sometimes applications may reuse the same value everywhere. However, it can be a hassle to manually
372
+ specify definitions for this sort of thing everywhere it might be used in the app. auryn mitigates
373
+ this problem by exposing the `Injector::defineParam()` method. Consider the following example ...
374
+
375
+ ```php
376
+ <?php
377
+ $myUniversalValue = 42;
378
+
379
+ class MyClass {
380
+ public $myValue;
381
+ public function __construct($myValue) {
382
+ $this->myValue = $myValue;
383
+ }
384
+ }
385
+
386
+ $injector = new Auryn\Injector;
387
+ $injector->defineParam('myValue', $myUniversalValue);
388
+ $obj = $injector->make('MyClass');
389
+ var_dump($obj->myValue === 42); // bool(true)
390
+ ```
391
+
392
+ Because we specified a global definition for `myValue`, all parameters that are not in some other
393
+ way defined (as below) that match the specified parameter name are auto-filled with the global value.
394
+ If a parameter matches any of the following criteria the global value is not used:
395
+
396
+ - A typehint
397
+ - A predefined injection definition
398
+ - A custom call time definition
399
+
400
+
401
+ ## Advanced Usage
402
+
403
+ ### Instance Sharing
404
+
405
+ One of the more ubiquitous plagues in modern OOP is the Singleton anti-pattern. Coders looking to
406
+ limit classes to a single instance often fall into the trap of using `static` Singleton
407
+ implementations for things like configuration classes and database connections. While it's often
408
+ necessary to prevent multiple instances of a class, the Singleton method spells death to testability
409
+ and should generally be avoided. `Auryn\Injector` makes sharing class instances across contexts a
410
+ triviality while allowing maximum testability and API transparency.
411
+
412
+ Let's consider how a typical problem facing object-oriented web applications is easily solved by
413
+ wiring together your application using auryn. Here, we want to inject a single database connection
414
+ instance across multiple layers of an application. We have a controller class that asks for a
415
+ DataMapper that requires a `PDO` database connection instance:
416
+
417
+ ```php
418
+ <?php
419
+ class DataMapper {
420
+ private $pdo;
421
+ public function __construct(PDO $pdo) {
422
+ $this->pdo = $pdo;
423
+ }
424
+ }
425
+
426
+ class MyController {
427
+ private $mapper;
428
+ public function __construct(DataMapper $mapper) {
429
+ $this->mapper = $mapper;
430
+ }
431
+ }
432
+
433
+ $db = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
434
+
435
+ $injector = new Auryn\Injector;
436
+ $injector->share($db);
437
+
438
+ $myController = $injector->make('MyController');
439
+ ```
440
+
441
+ In the above code, the `DataMapper` instance will be provisioned with the same `PDO` database
442
+ connection instance we originally shared. This example is contrived and overly simple, but the
443
+ implication should be clear:
444
+
445
+ > By sharing an instance of a class, `Auryn\Injector` will always use that instance when
446
+ > provisioning classes that type-hint the shared class.
447
+
448
+ ###### A Simpler Example
449
+
450
+ Let's look at a simple proof of concept:
451
+
452
+ ```php
453
+ <?php
454
+ class Person {
455
+ public $name = 'John Snow';
456
+ }
457
+
458
+ $injector = new Auryn\Injector;
459
+ $injector->share('Person');
460
+
461
+ $person = $injector->make('Person');
462
+ var_dump($person->name); // John Snow
463
+
464
+ $person->name = 'Arya Stark';
465
+
466
+ $anotherPerson = $injector->make('Person');
467
+ var_dump($anotherPerson->name); // Arya Stark
468
+ var_dump($person === $anotherPerson); // bool(true) because it's the same instance!
469
+ ```
470
+
471
+ Defining an object as shared will store the provisioned instance in the Injector's shared cache and
472
+ all future requests to the provider for an injected instance of that class will return the
473
+ originally created object. Note that in the above code, we shared the class name (`Person`)
474
+ instead of an actual instance. Sharing works with either a class name or an instance of a class.
475
+ The difference is that when you specify a class name, the Injector
476
+ will cache the shared instance the first time it is asked to create it.
477
+
478
+ > **NOTE:** Once the Injector caches a shared instance, call-time definitions passed to
479
+ `Auryn\Injector::make` will have no effect. Once shared, an instance will always be returned for
480
+ instantiations of its type until the object is un-shared or refreshed:
481
+
482
+ ### Instantiation Delegates
483
+
484
+ Often factory classes/methods are used to prepare an object for use after instantiation. auryn
485
+ allows you to integrate factories and builders directly into the injection process by specifying
486
+ callable instantiation delegates on a per-class basis. Let's look at a very basic example to
487
+ demonstrate the concept of injection delegates:
488
+
489
+ ```php
490
+ <?php
491
+ class MyComplexClass {
492
+ public $verification = false;
493
+ public function doSomethingAfterInstantiation() {
494
+ $this->verification = true;
495
+ }
496
+ }
497
+
498
+ $complexClassFactory = function() {
499
+ $obj = new MyComplexClass;
500
+ $obj->doSomethingAfterInstantiation();
501
+
502
+ return $obj;
503
+ };
504
+
505
+ $injector = new Auryn\Injector;
506
+ $injector->delegate('MyComplexClass', $complexClassFactory);
507
+
508
+ $obj = $injector->make('MyComplexClass');
509
+ var_dump($obj->verification); // bool(true)
510
+ ```
511
+
512
+ In the above code we delegate instantiation of the `MyComplexClass` class to a closure,
513
+ `$complexClassFactory`. Once this delegation is made, the Injector will return the results of the
514
+ specified closure when asked to instantiate `MyComplexClass`.
515
+
516
+ ###### Available Delegate Types
517
+
518
+ Any valid PHP callable may be registered as a class instantiation delegate using
519
+ `Auryn\Injector::delegate`. Additionally you may specify the name of a delegate class that
520
+ specifies an `__invoke` method and it will be automatically provisioned and have its `__invoke`
521
+ method called at delegation time. Instance methods from uninstantiated classes may also be specified
522
+ using the `['NonStaticClassName', 'factoryMethod']` construction. For example:
523
+
524
+ ```php
525
+ <?php
526
+ class SomeClassWithDelegatedInstantiation {
527
+ public $value = 0;
528
+ }
529
+ class SomeFactoryDependency {}
530
+ class MyFactory {
531
+ private $dependency;
532
+ function __construct(SomeFactoryDependency $dep) {
533
+ $this->dependency = $dep;
534
+ }
535
+ function __invoke() {
536
+ $obj = new SomeClassWithDelegatedInstantiation;
537
+ $obj->value = 1;
538
+ return $obj;
539
+ }
540
+ function factoryMethod() {
541
+ $obj = new SomeClassWithDelegatedInstantiation;
542
+ $obj->value = 2;
543
+ return $obj;
544
+ }
545
+ }
546
+
547
+ // Works because MyFactory specifies a magic __invoke method
548
+ $injector->delegate('SomeClassWithDelegatedInstantiation', 'MyFactory');
549
+ $obj = $injector->make('SomeClassWithDelegatedInstantiation');
550
+ var_dump($obj->value); // int(1)
551
+
552
+ // This also works
553
+ $injector->delegate('SomeClassWithDelegatedInstantiation', 'MyFactory::factoryMethod');
554
+ $obj = $injector->make('SomeClassWithDelegatedInstantiation');
555
+ $obj = $injector->make('SomeClassWithDelegatedInstantiation');
556
+ var_dump($obj->value); // int(2)
557
+ ```
558
+
559
+ ### Prepares and Setter Injection
560
+
561
+ Constructor injection is almost always preferable to setter injection. However, some APIs require
562
+ additional post-instantiation mutations. auryn accommodates these use cases with its
563
+ `Injector::prepare()` method. Users may register any class or interface name for post-instantiation
564
+ modification. Consider:
565
+
566
+ ```php
567
+ <?php
568
+
569
+ class MyClass {
570
+ public $myProperty = 0;
571
+ }
572
+
573
+ $injector->prepare('MyClass', function($myObj, $injector) {
574
+ $myObj->myProperty = 42;
575
+ });
576
+
577
+ $myObj = $injector->make('MyClass');
578
+ var_dump($myObj->myProperty); // int(42)
579
+ ```
580
+
581
+ While the above example is contrived, the usefulness should be clear.
582
+
583
+
584
+ ### Injecting for Execution
585
+
586
+ In addition to provisioning class instances using constructors, auryn can also recursively instantiate
587
+ the parameters of any [valid PHP callable](http://php.net/manual/en/language.types.callable.php).
588
+ The following examples all work:
589
+
590
+ ```php
591
+ <?php
592
+ $injector = new Auryn\Injector;
593
+ $injector->execute(function(){});
594
+ $injector->execute([$objectInstance, 'methodName']);
595
+ $injector->execute('globalFunctionName');
596
+ $injector->execute('MyStaticClass::myStaticMethod');
597
+ $injector->execute(['MyStaticClass', 'myStaticMethod']);
598
+ $injector->execute(['MyChildStaticClass', 'parent::myStaticMethod']);
599
+ $injector->execute('ClassThatHasMagicInvoke');
600
+ $injector->execute($instanceOfClassThatHasMagicInvoke);
601
+ $injector->execute('MyClass::myInstanceMethod');
602
+ ```
603
+
604
+ Additionally, you can pass in the name of a class for a non-static method and the injector will
605
+ automatically provision an instance of the class (subject to any definitions or shared instances
606
+ already stored by the injector) before provisioning and invoking the specified method:
607
+
608
+ ```php
609
+ <?php
610
+ class Dependency {}
611
+ class AnotherDependency {}
612
+ class Example {
613
+ function __construct(Dependency $dep){}
614
+ function myMethod(AnotherDependency $arg1, $arg2) {
615
+ return $arg2;
616
+ }
617
+ }
618
+
619
+ $injector = new Auryn\Injector;
620
+
621
+ // outputs: int(42)
622
+ var_dump($injector->execute('Example::myMethod', $args = [':arg2' => 42]));
623
+ ```
624
+
625
+
626
+ ### Dependency Resolution
627
+
628
+ `Auryn\Injector` resolves dependencies in the following order:
629
+
630
+ 1. If a shared instance exists for the class in question, the shared instance will always be returned
631
+ 2. If a delegate callable is assigned for a class, its return result will always be used
632
+ 3. If a call-time definition is passed to `Auryn\Injector::make`, that definition will be used
633
+ 4. If a pre-defined definition exists, it will be used
634
+ 5. If a dependency is type-hinted, the Injector will recursively instantiate it subject to any implementations or definitions
635
+ 6. If no type-hint exists and the parameter has a default value, the default value is injected
636
+ 7. If a global parameter value is defined that value is used
637
+ 8. Throw an exception because you did something stupid
638
+
639
+ ## Example Use Cases
640
+
641
+ Dependency Injection Containers (DIC) are generally misunderstood in the PHP community. One of the
642
+ primary culprits is the misuse of such containers in the mainstream application frameworks. Often,
643
+ these frameworks warp their DICs into Service Locator anti-patterns. This is a shame because a
644
+ good DIC should be the exact opposite of a Service Locator.
645
+
646
+ ###### auryn Is NOT A Service Locator!
647
+
648
+ There's a galaxy of differences between using a DIC to wire together your application versus
649
+ passing the DIC as a dependency to your objects (Service Locator). Service Locator (SL) is an
650
+ anti-pattern -- it hides class dependencies, makes code difficult to maintain and makes a liar of
651
+ your API.
652
+
653
+ When you pass a SL into your constructors it makes it difficult to determine what the class dependencies
654
+ really are. A `House` object depends on `Door` and `Window` objects. A `House` object DOES NOT depend
655
+ on an instance of `ServiceLocator` regardless of whether the `ServiceLocator` can provide `Door` and
656
+ `Window` objects.
657
+
658
+ In real life you wouldn't build a house by transporting the entire hardware store (hopefully) to
659
+ the construction site so you can access any parts you need. Instead, the foreman (`__construct()`)
660
+ asks for the specific parts that will be needed (`Door` and `Window`) and goes about procuring them.
661
+ Your objects should function in the same way; they should ask only for the specific dependencies
662
+ required to do their jobs. Giving the `House` access to the entire hardware store is at best poor
663
+ OOP style and at worst a maintainability nightmare. The takeaway here is this:
664
+
665
+ > **IMPORTANT:** do not use auryn like a Service Locator!
666
+
667
+
668
+ ### Avoiding Evil Singletons
669
+
670
+ A common difficulty in web applications is limiting the number of database connection instances.
671
+ It's wasteful and slow to open up new connections each time we need to talk to a database.
672
+ Unfortunately, using singletons to limit these instances makes code brittle and hard to test. Let's
673
+ see how we can use auryn to inject the same `PDO` instance across the entire scope of our application.
674
+
675
+ Say we have a service class that requires two separate data mappers to persist information to a database:
676
+
677
+ ```php
678
+ <?php
679
+
680
+ class HouseMapper {
681
+ private $pdo;
682
+ public function __construct(PDO $pdo) {
683
+ $this->pdo = $pdo;
684
+ }
685
+ public function find($houseId) {
686
+ $query = 'SELECT * FROM houses WHERE houseId = :houseId';
687
+
688
+ $stmt = $this->pdo->prepare($query);
689
+ $stmt->bindValue(':houseId', $houseId);
690
+
691
+ $stmt->setFetchMode(PDO::FETCH_CLASS, 'Model\\Entities\\House');
692
+ $stmt->execute();
693
+ $house = $stmt->fetch(PDO::FETCH_CLASS);
694
+
695
+ if (false === $house) {
696
+ throw new RecordNotFoundException(
697
+ 'No houses exist for the specified ID'
698
+ );
699
+ }
700
+
701
+ return $house;
702
+ }
703
+
704
+ // more data mapper methods here ...
705
+ }
706
+
707
+ class PersonMapper {
708
+ private $pdo;
709
+ public function __construct(PDO $pdo) {
710
+ $this->pdo = $pdo;
711
+ }
712
+ // data mapper methods here
713
+ }
714
+
715
+ class SomeService {
716
+ private $houseMapper;
717
+ private $personMapper;
718
+ public function __construct(HouseMapper $hm, PersonMapper $pm) {
719
+ $this->houseMapper = $hm;
720
+ $this->personMapper = $pm;
721
+ }
722
+ public function doSomething() {
723
+ // do something with the mappers
724
+ }
725
+ }
726
+ ```
727
+
728
+ In our wiring/bootstrap code, we simply instantiate the `PDO` instance once and share it in the
729
+ context of the `Injector`:
730
+
731
+ ```php
732
+ <?php
733
+ $pdo = new PDO('sqlite:some_sqlite_file.db');
734
+ $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
735
+
736
+ $injector = new Auryn\Injector;
737
+
738
+ $injector->share($pdo);
739
+ $mapper = $injector->make('SomeService');
740
+ ```
741
+
742
+ In the above code, the DIC instantiates our service class. More importantly, the data mapper classes
743
+ it generates to do so are injected *with the same database connection instance we originally shared*.
744
+
745
+ Of course, we don't have to manually instantiate our `PDO` instance. We could just as easily seed
746
+ the container with a definition for how to create the `PDO` object and let it handle things for us:
747
+
748
+ ```php
749
+ <?php
750
+ $injector->define('PDO', [
751
+ ':dsn' => 'sqlite:some_sqlite_file.db'
752
+ ]);
753
+ $injector->share('PDO');
754
+ $service = $injector->make('SomeService');
755
+ ```
756
+
757
+ In the above code, the injector will pass the string definition as the `$dsn` argument in the
758
+ `PDO::__construct` method and generate the shared PDO instance automatically only if one of the
759
+ classes it instantiates requires a `PDO` instance!
760
+
761
+
762
+
763
+ ### App-Bootstrapping
764
+
765
+ DICs should be used to wire together the disparate objects of your application into a cohesive
766
+ functional unit (generally at the bootstrap or front-controller stage of the application). One such
767
+ usage provides an elegant solution for one of the thorny problems in object-oriented (OO) web
768
+ applications: how to instantiate classes in a routed environment where the dependencies are not
769
+ known ahead of time.
770
+
771
+ Consider the following front controller code whose job is to:
772
+
773
+ 1. Load a list of application routes and pass them to the router
774
+ 2. Generate a model of the client's HTTP request
775
+ 3. Route the request instance given the application's route list
776
+ 4. Instantiate the routed controller and invoke a method appropriate to the HTTP request
777
+
778
+ ```php
779
+ <?php
780
+
781
+ define('CONTROLLER_ROUTES', '/hard/path/to/routes.xml');
782
+
783
+ $routeLoader = new RouteLoader();
784
+ $routes = $routeLoader->loadFromXml(CONTROLLER_ROUTES);
785
+ $router = new Router($routes);
786
+
787
+ $requestDetector = new RequestDetector();
788
+ $request = $requestDetector->detectFromSuperglobal($_SERVER);
789
+
790
+ $requestUri = $request->getUri();
791
+ $requestMethod = strtolower($request->getMethod());
792
+
793
+ $injector = new Auryn\Injector;
794
+ $injector->share($request);
795
+
796
+ try {
797
+ if (!$controllerClass = $router->route($requestUri, $requestMethod)) {
798
+ throw new NoRouteMatchException();
799
+ }
800
+
801
+ $controller = $injector->make($controllerClass);
802
+ $callableController = array($controller, $requestMethod);
803
+
804
+ if (!is_callable($callableController)) {
805
+ throw new MethodNotAllowedException();
806
+ } else {
807
+ $callableController();
808
+ }
809
+
810
+ } catch (NoRouteMatchException $e) {
811
+ // send 404 response
812
+ } catch (MethodNotAllowedException $e) {
813
+ // send 405 response
814
+ } catch (Exception $e) {
815
+ // send 500 response
816
+ }
817
+ ```
818
+
819
+ And elsewhere we have various controller classes, each of which ask for their own individual
820
+ dependencies:
821
+
822
+ ```php
823
+ <?php
824
+
825
+ class WidgetController {
826
+ private $request;
827
+ private $mapper;
828
+ public function __construct(Request $request, WidgetDataMapper $mapper) {
829
+ $this->request = $request;
830
+ $this->mapper = $mapper;
831
+ }
832
+ public function get() {
833
+ // do something for HTTP GET requests
834
+ }
835
+ public function post() {
836
+ // do something for HTTP POST requests
837
+ }
838
+ }
839
+ ```
840
+
841
+ In the above example the auryn DIC allows us to write fully testable, fully OO controllers that ask
842
+ for their dependencies. Because the DIC recursively instantiates the dependencies of objects it
843
+ creates we have no need to pass around a Service Locator. Additionally, this example shows how we can
844
+ eliminate evil Singletons using the sharing capabilities of the auryn DIC. In the front controller
845
+ code, we share the request object so that any classes instantiated by the `Auryn\Injector` that ask
846
+ for a `Request` will receive the same instance. This feature not only helps eliminate Singletons,
847
+ but also the need for hard-to-test `static` properties.
vendor/rdlowrey/auryn/composer.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "rdlowrey/auryn",
3
+ "homepage": "https://github.com/rdlowrey/auryn",
4
+ "description": "Auryn is a dependency injector for bootstrapping object-oriented PHP applications.",
5
+ "keywords": ["dependency injection", "dic", "ioc"],
6
+ "license": "MIT",
7
+ "authors": [
8
+ {
9
+ "name": "Daniel Lowrey",
10
+ "email": "rdlowrey@gmail.com",
11
+ "role": "Creator / Main Developer",
12
+ "homepage": "https://github.com/rdlowrey"
13
+ },
14
+ {
15
+ "name": "Levi Morrison",
16
+ "email": "levim@php.net",
17
+ "homepage": "http://morrisonlevi.github.com/",
18
+ "role": "Developer"
19
+ },
20
+ {
21
+ "name": "Dan Ackroyd",
22
+ "email": "Danack@basereality.com",
23
+ "homepage": "http://www.basereality.com",
24
+ "role": "Developer"
25
+ }
26
+ ],
27
+ "require": {
28
+ "php": ">=5.3.0"
29
+ },
30
+ "require-dev": {
31
+ "phpunit/phpunit": "^4.7",
32
+ "fabpot/php-cs-fixer": "~1.9",
33
+ "athletic/athletic": "~0.1"
34
+ },
35
+ "autoload": {
36
+ "psr-4": {
37
+ "Auryn\\": "lib/"
38
+ }
39
+ },
40
+ "autoload-dev": {
41
+ "psr-4": {
42
+ "Auryn\\Test\\": "test/"
43
+ },
44
+ "files": ["test/fixtures.php"]
45
+ }
46
+ }
vendor/rdlowrey/auryn/lib/CachingReflector.php ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class CachingReflector implements Reflector
6
+ {
7
+ const CACHE_KEY_CLASSES = 'auryn.refls.classes.';
8
+ const CACHE_KEY_CTORS = 'auryn.refls.ctors.';
9
+ const CACHE_KEY_CTOR_PARAMS = 'auryn.refls.ctor-params.';
10
+ const CACHE_KEY_FUNCS = 'auryn.refls.funcs.';
11
+ const CACHE_KEY_METHODS = 'auryn.refls.methods.';
12
+
13
+ private $reflector;
14
+ private $cache;
15
+
16
+ public function __construct(Reflector $reflector = null, ReflectionCache $cache = null)
17
+ {
18
+ $this->reflector = $reflector ?: new StandardReflector;
19
+ $this->cache = $cache ?: new ReflectionCacheArray;
20
+ }
21
+
22
+ public function getClass($class)
23
+ {
24
+ $cacheKey = self::CACHE_KEY_CLASSES . strtolower($class);
25
+
26
+ if (!$reflectionClass = $this->cache->fetch($cacheKey)) {
27
+ $reflectionClass = new \ReflectionClass($class);
28
+ $this->cache->store($cacheKey, $reflectionClass);
29
+ }
30
+
31
+ return $reflectionClass;
32
+ }
33
+
34
+ public function getCtor($class)
35
+ {
36
+ $cacheKey = self::CACHE_KEY_CTORS . strtolower($class);
37
+
38
+ $reflectedCtor = $this->cache->fetch($cacheKey);
39
+
40
+ if ($reflectedCtor === false) {
41
+ $reflectionClass = $this->getClass($class);
42
+ $reflectedCtor = $reflectionClass->getConstructor();
43
+ $this->cache->store($cacheKey, $reflectedCtor);
44
+ }
45
+
46
+ return $reflectedCtor;
47
+ }
48
+
49
+ public function getCtorParams($class)
50
+ {
51
+ $cacheKey = self::CACHE_KEY_CTOR_PARAMS . strtolower($class);
52
+
53
+ $reflectedCtorParams = $this->cache->fetch($cacheKey);
54
+
55
+ if (false !== $reflectedCtorParams) {
56
+ return $reflectedCtorParams;
57
+ } elseif ($reflectedCtor = $this->getCtor($class)) {
58
+ $reflectedCtorParams = $reflectedCtor->getParameters();
59
+ } else {
60
+ $reflectedCtorParams = null;
61
+ }
62
+
63
+ $this->cache->store($cacheKey, $reflectedCtorParams);
64
+
65
+ return $reflectedCtorParams;
66
+ }
67
+
68
+ public function getParamTypeHint(\ReflectionFunctionAbstract $function, \ReflectionParameter $param)
69
+ {
70
+ $lowParam = strtolower($param->name);
71
+
72
+ if ($function instanceof \ReflectionMethod) {
73
+ $lowClass = strtolower($function->class);
74
+ $lowMethod = strtolower($function->name);
75
+ $paramCacheKey = self::CACHE_KEY_CLASSES . "{$lowClass}.{$lowMethod}.param-{$lowParam}";
76
+ } else {
77
+ $lowFunc = strtolower($function->name);
78
+ $paramCacheKey = ($lowFunc !== '{closure}')
79
+ ? self::CACHE_KEY_FUNCS . ".{$lowFunc}.param-{$lowParam}"
80
+ : null;
81
+ }
82
+
83
+ $typeHint = ($paramCacheKey === null) ? false : $this->cache->fetch($paramCacheKey);
84
+
85
+ if (false !== $typeHint) {
86
+ return $typeHint;
87
+ }
88
+
89
+ if ($reflectionClass = $param->getClass()) {
90
+ $typeHint = $reflectionClass->getName();
91
+ $classCacheKey = self::CACHE_KEY_CLASSES . strtolower($typeHint);
92
+ $this->cache->store($classCacheKey, $reflectionClass);
93
+ } else {
94
+ $typeHint = null;
95
+ }
96
+
97
+ $this->cache->store($paramCacheKey, $typeHint);
98
+
99
+ return $typeHint;
100
+ }
101
+
102
+ public function getFunction($functionName)
103
+ {
104
+ $lowFunc = strtolower($functionName);
105
+ $cacheKey = self::CACHE_KEY_FUNCS . $lowFunc;
106
+
107
+ $reflectedFunc = $this->cache->fetch($cacheKey);
108
+
109
+ if (false === $reflectedFunc) {
110
+ $reflectedFunc = new \ReflectionFunction($functionName);
111
+ $this->cache->store($cacheKey, $reflectedFunc);
112
+ }
113
+
114
+ return $reflectedFunc;
115
+ }
116
+
117
+ public function getMethod($classNameOrInstance, $methodName)
118
+ {
119
+ $className = is_string($classNameOrInstance)
120
+ ? $classNameOrInstance
121
+ : get_class($classNameOrInstance);
122
+
123
+ $cacheKey = self::CACHE_KEY_METHODS . strtolower($className) . '.' . strtolower($methodName);
124
+
125
+ if (!$reflectedMethod = $this->cache->fetch($cacheKey)) {
126
+ $reflectedMethod = new \ReflectionMethod($className, $methodName);
127
+ $this->cache->store($cacheKey, $reflectedMethod);
128
+ }
129
+
130
+ return $reflectedMethod;
131
+ }
132
+ }
vendor/rdlowrey/auryn/lib/ConfigException.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class ConfigException extends InjectorException
6
+ {
7
+ }
vendor/rdlowrey/auryn/lib/Executable.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class Executable
6
+ {
7
+ private $callableReflection;
8
+ private $invocationObject;
9
+ private $isInstanceMethod;
10
+
11
+ public function __construct(\ReflectionFunctionAbstract $reflFunc, $invocationObject = null)
12
+ {
13
+ if ($reflFunc instanceof \ReflectionMethod) {
14
+ $this->isInstanceMethod = true;
15
+ $this->setMethodCallable($reflFunc, $invocationObject);
16
+ } else {
17
+ $this->isInstanceMethod = false;
18
+ $this->callableReflection = $reflFunc;
19
+ }
20
+ }
21
+
22
+ private function setMethodCallable(\ReflectionMethod $reflection, $invocationObject)
23
+ {
24
+ if (is_object($invocationObject)) {
25
+ $this->callableReflection = $reflection;
26
+ $this->invocationObject = $invocationObject;
27
+ } elseif ($reflection->isStatic()) {
28
+ $this->callableReflection = $reflection;
29
+ } else {
30
+ throw new \InvalidArgumentException(
31
+ 'ReflectionMethod callables must specify an invocation object'
32
+ );
33
+ }
34
+ }
35
+
36
+ public function __invoke()
37
+ {
38
+ $args = func_get_args();
39
+ $reflection = $this->callableReflection;
40
+
41
+ if ($this->isInstanceMethod) {
42
+ return $reflection->invokeArgs($this->invocationObject, $args);
43
+ }
44
+
45
+ return $this->callableReflection->isClosure()
46
+ ? $this->invokeClosureCompat($reflection, $args)
47
+ : $reflection->invokeArgs($args);
48
+ }
49
+
50
+ /**
51
+ * @TODO Remove this extra indirection when 5.3 support is dropped
52
+ */
53
+ private function invokeClosureCompat($reflection, $args)
54
+ {
55
+ if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
56
+ $scope = $reflection->getClosureScopeClass();
57
+ $closure = \Closure::bind(
58
+ $reflection->getClosure(),
59
+ $reflection->getClosureThis(),
60
+ $scope ? $scope->name : null
61
+ );
62
+ return call_user_func_array($closure, $args);
63
+ } else {
64
+ return $reflection->invokeArgs($args);
65
+ }
66
+ }
67
+
68
+ public function getCallableReflection()
69
+ {
70
+ return $this->callableReflection;
71
+ }
72
+
73
+ public function getInvocationObject()
74
+ {
75
+ return $this->invocationObject;
76
+ }
77
+
78
+ public function isInstanceMethod()
79
+ {
80
+ return $this->isInstanceMethod;
81
+ }
82
+ }
vendor/rdlowrey/auryn/lib/InjectionException.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class InjectionException extends InjectorException
6
+ {
7
+ public $dependencyChain;
8
+
9
+ public function __construct(array $inProgressMakes, $message = "", $code = 0, \Exception $previous = null)
10
+ {
11
+ $this->dependencyChain = array_flip($inProgressMakes);
12
+ ksort($this->dependencyChain);
13
+
14
+ parent::__construct($message, $code, $previous);
15
+ }
16
+
17
+ /**
18
+ * Add a human readable version of the invalid callable to the standard 'invalid invokable' message.
19
+ */
20
+ public static function fromInvalidCallable(
21
+ array $inProgressMakes,
22
+ $callableOrMethodStr,
23
+ \Exception $previous = null
24
+ ) {
25
+ $callableString = null;
26
+
27
+ if (is_string($callableOrMethodStr)) {
28
+ $callableString .= $callableOrMethodStr;
29
+ } else if (is_array($callableOrMethodStr) &&
30
+ array_key_exists(0, $callableOrMethodStr) &&
31
+ array_key_exists(0, $callableOrMethodStr)) {
32
+ if (is_string($callableOrMethodStr[0]) && is_string($callableOrMethodStr[1])) {
33
+ $callableString .= $callableOrMethodStr[0].'::'.$callableOrMethodStr[1];
34
+ } else if (is_object($callableOrMethodStr[0]) && is_string($callableOrMethodStr[1])) {
35
+ $callableString .= sprintf(
36
+ "[object(%s), '%s']",
37
+ get_class($callableOrMethodStr[0]),
38
+ $callableOrMethodStr[1]
39
+ );
40
+ }
41
+ }
42
+
43
+ if ($callableString) {
44
+ // Prevent accidental usage of long strings from filling logs.
45
+ $callableString = substr($callableString, 0, 250);
46
+ $message = sprintf(
47
+ "%s. Invalid callable was '%s'",
48
+ Injector::M_INVOKABLE,
49
+ $callableString
50
+ );
51
+ } else {
52
+ $message = \Auryn\Injector::M_INVOKABLE;
53
+ }
54
+
55
+ return new self($inProgressMakes, $message, Injector::E_INVOKABLE, $previous);
56
+ }
57
+
58
+ /**
59
+ * Returns the hierarchy of dependencies that were being created when
60
+ * the exception occurred.
61
+ * @return array
62
+ */
63
+ public function getDependencyChain()
64
+ {
65
+ return $this->dependencyChain;
66
+ }
67
+ }
vendor/rdlowrey/auryn/lib/Injector.php ADDED
@@ -0,0 +1,738 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class Injector
6
+ {
7
+ const A_RAW = ':';
8
+ const A_DELEGATE = '+';
9
+ const A_DEFINE = '@';
10
+ const I_BINDINGS = 1;
11
+ const I_DELEGATES = 2;
12
+ const I_PREPARES = 4;
13
+ const I_ALIASES = 8;
14
+ const I_SHARES = 16;
15
+ const I_ALL = 17;
16
+
17
+ const E_NON_EMPTY_STRING_ALIAS = 1;
18
+ const M_NON_EMPTY_STRING_ALIAS = "Invalid alias: non-empty string required at arguments 1 and 2";
19
+ const E_SHARED_CANNOT_ALIAS = 2;
20
+ const M_SHARED_CANNOT_ALIAS = "Cannot alias class %s to %s because it is currently shared";
21
+ const E_SHARE_ARGUMENT = 3;
22
+ const M_SHARE_ARGUMENT = "%s::share() requires a string class name or object instance at Argument 1; %s specified";
23
+ const E_ALIASED_CANNOT_SHARE = 4;
24
+ const M_ALIASED_CANNOT_SHARE = "Cannot share class %s because it is currently aliased to %s";
25
+ const E_INVOKABLE = 5;
26
+ const M_INVOKABLE = "Invalid invokable: callable or provisional string required";
27
+ const E_NON_PUBLIC_CONSTRUCTOR = 6;
28
+ const M_NON_PUBLIC_CONSTRUCTOR = "Cannot instantiate protected/private constructor in class %s";
29
+ const E_NEEDS_DEFINITION = 7;
30
+ const M_NEEDS_DEFINITION = "Injection definition required for %s %s";
31
+ const E_MAKE_FAILURE = 8;
32
+ const M_MAKE_FAILURE = "Could not make %s: %s";
33
+ const E_UNDEFINED_PARAM = 9;
34
+ const M_UNDEFINED_PARAM = "No definition available to provision typeless parameter \$%s at position %d in %s()";
35
+ const E_DELEGATE_ARGUMENT = 10;
36
+ const M_DELEGATE_ARGUMENT = "%s::delegate expects a valid callable or executable class::method string at Argument 2%s";
37
+ const E_CYCLIC_DEPENDENCY = 11;
38
+ const M_CYCLIC_DEPENDENCY = "Detected a cyclic dependency while provisioning %s";
39
+ const E_MAKING_FAILED = 12;
40
+ const M_MAKING_FAILED = "Making %s did not result in an object, instead result is of type '%s'";
41
+
42
+ private $reflector;
43
+ private $classDefinitions = array();
44
+ private $paramDefinitions = array();
45
+ private $aliases = array();
46
+ private $shares = array();
47
+ private $prepares = array();
48
+ private $delegates = array();
49
+ private $inProgressMakes = array();
50
+
51
+ public function __construct(Reflector $reflector = null)
52
+ {
53
+ $this->reflector = $reflector ?: new CachingReflector;
54
+ }
55
+
56
+ public function __clone()
57
+ {
58
+ $this->inProgressMakes = array();
59
+ }
60
+
61
+ /**
62
+ * Define instantiation directives for the specified class
63
+ *
64
+ * @param string $name The class (or alias) whose constructor arguments we wish to define
65
+ * @param array $args An array mapping parameter names to values/instructions
66
+ * @return self
67
+ */
68
+ public function define($name, array $args)
69
+ {
70
+ list(, $normalizedName) = $this->resolveAlias($name);
71
+ $this->classDefinitions[$normalizedName] = $args;
72
+
73
+ return $this;
74
+ }
75
+
76
+ /**
77
+ * Assign a global default value for all parameters named $paramName
78
+ *
79
+ * Global parameter definitions are only used for parameters with no typehint, pre-defined or
80
+ * call-time definition.
81
+ *
82
+ * @param string $paramName The parameter name for which this value applies
83
+ * @param mixed $value The value to inject for this parameter name
84
+ * @return self
85
+ */
86
+ public function defineParam($paramName, $value)
87
+ {
88
+ $this->paramDefinitions[$paramName] = $value;
89
+
90
+ return $this;
91
+ }
92
+
93
+ /**
94
+ * Define an alias for all occurrences of a given typehint
95
+ *
96
+ * Use this method to specify implementation classes for interface and abstract class typehints.
97
+ *
98
+ * @param string $original The typehint to replace
99
+ * @param string $alias The implementation name
100
+ * @throws ConfigException if any argument is empty or not a string
101
+ * @return self
102
+ */
103
+ public function alias($original, $alias)
104
+ {
105
+ if (empty($original) || !is_string($original)) {
106
+ throw new ConfigException(
107
+ self::M_NON_EMPTY_STRING_ALIAS,
108
+ self::E_NON_EMPTY_STRING_ALIAS
109
+ );
110
+ }
111
+ if (empty($alias) || !is_string($alias)) {
112
+ throw new ConfigException(
113
+ self::M_NON_EMPTY_STRING_ALIAS,
114
+ self::E_NON_EMPTY_STRING_ALIAS
115
+ );
116
+ }
117
+
118
+ $originalNormalized = $this->normalizeName($original);
119
+
120
+ if (isset($this->shares[$originalNormalized])) {
121
+ throw new ConfigException(
122
+ sprintf(
123
+ self::M_SHARED_CANNOT_ALIAS,
124
+ $this->normalizeName(get_class($this->shares[$originalNormalized])),
125
+ $alias
126
+ ),
127
+ self::E_SHARED_CANNOT_ALIAS
128
+ );
129
+ }
130
+
131
+ if (array_key_exists($originalNormalized, $this->shares)) {
132
+ $aliasNormalized = $this->normalizeName($alias);
133
+ $this->shares[$aliasNormalized] = null;
134
+ unset($this->shares[$originalNormalized]);
135
+ }
136
+
137
+ $this->aliases[$originalNormalized] = $alias;
138
+
139
+ return $this;
140
+ }
141
+
142
+ private function normalizeName($className)
143
+ {
144
+ return ltrim(strtolower($className), '\\');
145
+ }
146
+
147
+ /**
148
+ * Share the specified class/instance across the Injector context
149
+ *
150
+ * @param mixed $nameOrInstance The class or object to share
151
+ * @throws ConfigException if $nameOrInstance is not a string or an object
152
+ * @return self
153
+ */
154
+ public function share($nameOrInstance)
155
+ {
156
+ if (is_string($nameOrInstance)) {
157
+ $this->shareClass($nameOrInstance);
158
+ } elseif (is_object($nameOrInstance)) {
159
+ $this->shareInstance($nameOrInstance);
160
+ } else {
161
+ throw new ConfigException(
162
+ sprintf(
163
+ self::M_SHARE_ARGUMENT,
164
+ __CLASS__,
165
+ gettype($nameOrInstance)
166
+ ),
167
+ self::E_SHARE_ARGUMENT
168
+ );
169
+ }
170
+
171
+ return $this;
172
+ }
173
+
174
+ private function shareClass($nameOrInstance)
175
+ {
176
+ list(, $normalizedName) = $this->resolveAlias($nameOrInstance);
177
+ $this->shares[$normalizedName] = isset($this->shares[$normalizedName])
178
+ ? $this->shares[$normalizedName]
179
+ : null;
180
+ }
181
+
182
+ private function resolveAlias($name)
183
+ {
184
+ $normalizedName = $this->normalizeName($name);
185
+ if (isset($this->aliases[$normalizedName])) {
186
+ $name = $this->aliases[$normalizedName];
187
+ $normalizedName = $this->normalizeName($name);
188
+ }
189
+
190
+ return array($name, $normalizedName);
191
+ }
192
+
193
+ private function shareInstance($obj)
194
+ {
195
+ $normalizedName = $this->normalizeName(get_class($obj));
196
+ if (isset($this->aliases[$normalizedName])) {
197
+ // You cannot share an instance of a class name that is already aliased
198
+ throw new ConfigException(
199
+ sprintf(
200
+ self::M_ALIASED_CANNOT_SHARE,
201
+ $normalizedName,
202
+ $this->aliases[$normalizedName]
203
+ ),
204
+ self::E_ALIASED_CANNOT_SHARE
205
+ );
206
+ }
207
+ $this->shares[$normalizedName] = $obj;
208
+ }
209
+
210
+ /**
211
+ * Register a prepare callable to modify/prepare objects of type $name after instantiation
212
+ *
213
+ * Any callable or provisionable invokable may be specified. Preparers are passed two
214
+ * arguments: the instantiated object to be mutated and the current Injector instance.
215
+ *
216
+ * @param string $name
217
+ * @param mixed $callableOrMethodStr Any callable or provisionable invokable method
218
+ * @throws InjectionException if $callableOrMethodStr is not a callable.
219
+ * See https://github.com/rdlowrey/auryn#injecting-for-execution
220
+ * @return self
221
+ */
222
+ public function prepare($name, $callableOrMethodStr)
223
+ {
224
+ if ($this->isExecutable($callableOrMethodStr) === false) {
225
+ throw InjectionException::fromInvalidCallable(
226
+ $this->inProgressMakes,
227
+ self::E_INVOKABLE,
228
+ $callableOrMethodStr
229
+ );
230
+ }
231
+
232
+ list(, $normalizedName) = $this->resolveAlias($name);
233
+ $this->prepares[$normalizedName] = $callableOrMethodStr;
234
+
235
+ return $this;
236
+ }
237
+
238
+ private function isExecutable($exe)
239
+ {
240
+ if (is_callable($exe)) {
241
+ return true;
242
+ }
243
+ if (is_string($exe) && method_exists($exe, '__invoke')) {
244
+ return true;
245
+ }
246
+ if (is_array($exe) && isset($exe[0], $exe[1]) && method_exists($exe[0], $exe[1])) {
247
+ return true;
248
+ }
249
+
250
+ return false;
251
+ }
252
+
253
+ /**
254
+ * Delegate the creation of $name instances to the specified callable
255
+ *
256
+ * @param string $name
257
+ * @param mixed $callableOrMethodStr Any callable or provisionable invokable method
258
+ * @throws ConfigException if $callableOrMethodStr is not a callable.
259
+ * @return self
260
+ */
261
+ public function delegate($name, $callableOrMethodStr)
262
+ {
263
+ if ($this->isExecutable($callableOrMethodStr) === false) {
264
+ $errorDetail = '';
265
+ if (is_string($callableOrMethodStr)) {
266
+ $errorDetail = " but received '$callableOrMethodStr'";
267
+ } elseif (is_array($callableOrMethodStr) &&
268
+ count($callableOrMethodStr) === 2 &&
269
+ array_key_exists(0, $callableOrMethodStr) &&
270
+ array_key_exists(1, $callableOrMethodStr)
271
+ ) {
272
+ if (is_string($callableOrMethodStr[0]) && is_string($callableOrMethodStr[1])) {
273
+ $errorDetail = " but received ['".$callableOrMethodStr[0]."', '".$callableOrMethodStr[1]."']";
274
+ }
275
+ }
276
+ throw new ConfigException(
277
+ sprintf(self::M_DELEGATE_ARGUMENT, __CLASS__, $errorDetail),
278
+ self::E_DELEGATE_ARGUMENT
279
+ );
280
+ }
281
+ $normalizedName = $this->normalizeName($name);
282
+ $this->delegates[$normalizedName] = $callableOrMethodStr;
283
+
284
+ return $this;
285
+ }
286
+
287
+ /**
288
+ * Retrieve stored data for the specified definition type
289
+ *
290
+ * Exposes introspection of existing binds/delegates/shares/etc for decoration and composition.
291
+ *
292
+ * @param string $nameFilter An optional class name filter
293
+ * @param int $typeFilter A bitmask of Injector::* type constant flags
294
+ * @return array
295
+ */
296
+ public function inspect($nameFilter = null, $typeFilter = null)
297
+ {
298
+ $result = array();
299
+ $name = $nameFilter ? $this->normalizeName($nameFilter) : null;
300
+
301
+ if (empty($typeFilter)) {
302
+ $typeFilter = self::I_ALL;
303
+ }
304
+
305
+ $types = array(
306
+ self::I_BINDINGS => "classDefinitions",
307
+ self::I_DELEGATES => "delegates",
308
+ self::I_PREPARES => "prepares",
309
+ self::I_ALIASES => "aliases",
310
+ self::I_SHARES => "shares"
311
+ );
312
+
313
+ foreach ($types as $type => $source) {
314
+ if ($typeFilter & $type) {
315
+ $result[$type] = $this->filter($this->{$source}, $name);
316
+ }
317
+ }
318
+
319
+ return $result;
320
+ }
321
+
322
+ private function filter($source, $name)
323
+ {
324
+ if (empty($name)) {
325
+ return $source;
326
+ } elseif (array_key_exists($name, $source)) {
327
+ return array($name => $source[$name]);
328
+ } else {
329
+ return array();
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Instantiate/provision a class instance
335
+ *
336
+ * @param string $name
337
+ * @param array $args
338
+ * @throws InjectionException if a cyclic gets detected when provisioning
339
+ * @return mixed
340
+ */
341
+ public function make($name, array $args = array())
342
+ {
343
+ list($className, $normalizedClass) = $this->resolveAlias($name);
344
+
345
+ if (isset($this->inProgressMakes[$normalizedClass])) {
346
+ throw new InjectionException(
347
+ $this->inProgressMakes,
348
+ sprintf(
349
+ self::M_CYCLIC_DEPENDENCY,
350
+ $className
351
+ ),
352
+ self::E_CYCLIC_DEPENDENCY
353
+ );
354
+ }
355
+
356
+ $this->inProgressMakes[$normalizedClass] = count($this->inProgressMakes);
357
+
358
+ // isset() is used specifically here because classes may be marked as "shared" before an
359
+ // instance is stored. In these cases the class is "shared," but it has a null value and
360
+ // instantiation is needed.
361
+ if (isset($this->shares[$normalizedClass])) {
362
+ unset($this->inProgressMakes[$normalizedClass]);
363
+
364
+ return $this->shares[$normalizedClass];
365
+ }
366
+
367
+ if (isset($this->delegates[$normalizedClass])) {
368
+ $executable = $this->buildExecutable($this->delegates[$normalizedClass]);
369
+ $reflectionFunction = $executable->getCallableReflection();
370
+ $args = $this->provisionFuncArgs($reflectionFunction, $args);
371
+ $obj = call_user_func_array(array($executable, '__invoke'), $args);
372
+ } else {
373
+ $obj = $this->provisionInstance($className, $normalizedClass, $args);
374
+ }
375
+
376
+ $obj = $this->prepareInstance($obj, $normalizedClass);
377
+
378
+ if (array_key_exists($normalizedClass, $this->shares)) {
379
+ $this->shares[$normalizedClass] = $obj;
380
+ }
381
+
382
+ unset($this->inProgressMakes[$normalizedClass]);
383
+
384
+ return $obj;
385
+ }
386
+
387
+ private function provisionInstance($className, $normalizedClass, array $definition)
388
+ {
389
+ try {
390
+ $ctor = $this->reflector->getCtor($className);
391
+
392
+ if (!$ctor) {
393
+ $obj = $this->instantiateWithoutCtorParams($className);
394
+ } elseif (!$ctor->isPublic()) {
395
+ throw new InjectionException(
396
+ $this->inProgressMakes,
397
+ sprintf(self::M_NON_PUBLIC_CONSTRUCTOR, $className),
398
+ self::E_NON_PUBLIC_CONSTRUCTOR
399
+ );
400
+ } elseif ($ctorParams = $this->reflector->getCtorParams($className)) {
401
+ $reflClass = $this->reflector->getClass($className);
402
+ $definition = isset($this->classDefinitions[$normalizedClass])
403
+ ? array_replace($this->classDefinitions[$normalizedClass], $definition)
404
+ : $definition;
405
+ $args = $this->provisionFuncArgs($ctor, $definition, $ctorParams);
406
+ $obj = $reflClass->newInstanceArgs($args);
407
+ } else {
408
+ $obj = $this->instantiateWithoutCtorParams($className);
409
+ }
410
+
411
+ return $obj;
412
+ } catch (\ReflectionException $e) {
413
+ throw new InjectionException(
414
+ $this->inProgressMakes,
415
+ sprintf(self::M_MAKE_FAILURE, $className, $e->getMessage()),
416
+ self::E_MAKE_FAILURE,
417
+ $e
418
+ );
419
+ }
420
+ }
421
+
422
+ private function instantiateWithoutCtorParams($className)
423
+ {
424
+ $reflClass = $this->reflector->getClass($className);
425
+
426
+ if (!$reflClass->isInstantiable()) {
427
+ $type = $reflClass->isInterface() ? 'interface' : 'abstract class';
428
+ throw new InjectionException(
429
+ $this->inProgressMakes,
430
+ sprintf(self::M_NEEDS_DEFINITION, $type, $className),
431
+ self::E_NEEDS_DEFINITION
432
+ );
433
+ }
434
+
435
+ return new $className;
436
+ }
437
+
438
+ private function provisionFuncArgs(\ReflectionFunctionAbstract $reflFunc, array $definition, array $reflParams = null)
439
+ {
440
+ $args = array();
441
+
442
+ // @TODO store this in ReflectionStorage
443
+ if (!isset($reflParams)) {
444
+ $reflParams = $reflFunc->getParameters();
445
+ }
446
+
447
+ foreach ($reflParams as $i => $reflParam) {
448
+ $name = $reflParam->name;
449
+
450
+ if (isset($definition[$i]) || array_key_exists($i, $definition)) {
451
+ // indexed arguments take precedence over named parameters
452
+ $arg = $definition[$i];
453
+ } elseif (isset($definition[$name]) || array_key_exists($name, $definition)) {
454
+ // interpret the param as a class name to be instantiated
455
+ $arg = $this->make($definition[$name]);
456
+ } elseif (($prefix = self::A_RAW . $name) && (isset($definition[$prefix]) || array_key_exists($prefix, $definition))) {
457
+ // interpret the param as a raw value to be injected
458
+ $arg = $definition[$prefix];
459
+ } elseif (($prefix = self::A_DELEGATE . $name) && isset($definition[$prefix])) {
460
+ // interpret the param as an invokable delegate
461
+ $arg = $this->buildArgFromDelegate($name, $definition[$prefix]);
462
+ } elseif (($prefix = self::A_DEFINE . $name) && isset($definition[$prefix])) {
463
+ // interpret the param as a class definition
464
+ $arg = $this->buildArgFromParamDefineArr($definition[$prefix]);
465
+ } elseif (!$arg = $this->buildArgFromTypeHint($reflFunc, $reflParam)) {
466
+ $arg = $this->buildArgFromReflParam($reflParam);
467
+ }
468
+
469
+ $args[] = $arg;
470
+ }
471
+
472
+ return $args;
473
+ }
474
+
475
+ private function buildArgFromParamDefineArr($definition)
476
+ {
477
+ if (!is_array($definition)) {
478
+ throw new InjectionException(
479
+ $this->inProgressMakes
480
+ // @TODO Add message
481
+ );
482
+ }
483
+
484
+ if (!isset($definition[0], $definition[1])) {
485
+ throw new InjectionException(
486
+ $this->inProgressMakes
487
+ // @TODO Add message
488
+ );
489
+ }
490
+
491
+ list($class, $definition) = $definition;
492
+
493
+ return $this->make($class, $definition);
494
+ }
495
+
496
+ private function buildArgFromDelegate($paramName, $callableOrMethodStr)
497
+ {
498
+ if ($this->isExecutable($callableOrMethodStr) === false) {
499
+ throw InjectionException::fromInvalidCallable(
500
+ $this->inProgressMakes,
501
+ $callableOrMethodStr
502
+ );
503
+ }
504
+
505
+ $executable = $this->buildExecutable($callableOrMethodStr);
506
+
507
+ return $executable($paramName, $this);
508
+ }
509
+
510
+ private function buildArgFromTypeHint(\ReflectionFunctionAbstract $reflFunc, \ReflectionParameter $reflParam)
511
+ {
512
+ $typeHint = $this->reflector->getParamTypeHint($reflFunc, $reflParam);
513
+
514
+ if (!$typeHint) {
515
+ $obj = null;
516
+ } elseif ($reflParam->isDefaultValueAvailable()) {
517
+ $normalizedName = $this->normalizeName($typeHint);
518
+ // Injector has been told explicitly how to make this type
519
+ if (isset($this->aliases[$normalizedName]) ||
520
+ isset($this->delegates[$normalizedName]) ||
521
+ isset($this->shares[$normalizedName])) {
522
+ $obj = $this->make($typeHint);
523
+ } else {
524
+ $obj = $reflParam->getDefaultValue();
525
+ }
526
+ } else {
527
+ $obj = $this->make($typeHint);
528
+ }
529
+
530
+ return $obj;
531
+ }
532
+
533
+ private function buildArgFromReflParam(\ReflectionParameter $reflParam)
534
+ {
535
+ if (array_key_exists($reflParam->name, $this->paramDefinitions)) {
536
+ $arg = $this->paramDefinitions[$reflParam->name];
537
+ } elseif ($reflParam->isDefaultValueAvailable()) {
538
+ $arg = $reflParam->getDefaultValue();
539
+ } elseif ($reflParam->isOptional()) {
540
+ // This branch is required to work around PHP bugs where a parameter is optional
541
+ // but has no default value available through reflection. Specifically, PDO exhibits
542
+ // this behavior.
543
+ $arg = null;
544
+ } else {
545
+ $reflFunc = $reflParam->getDeclaringFunction();
546
+ $classWord = ($reflFunc instanceof \ReflectionMethod)
547
+ ? $reflFunc->getDeclaringClass()->name . '::'
548
+ : '';
549
+ $funcWord = $classWord . $reflFunc->name;
550
+
551
+ throw new InjectionException(
552
+ $this->inProgressMakes,
553
+ sprintf(
554
+ self::M_UNDEFINED_PARAM,
555
+ $reflParam->name,
556
+ $reflParam->getPosition(),
557
+ $funcWord
558
+ ),
559
+ self::E_UNDEFINED_PARAM
560
+ );
561
+ }
562
+
563
+ return $arg;
564
+ }
565
+
566
+ private function prepareInstance($obj, $normalizedClass)
567
+ {
568
+ if (isset($this->prepares[$normalizedClass])) {
569
+ $prepare = $this->prepares[$normalizedClass];
570
+ $executable = $this->buildExecutable($prepare);
571
+ $result = $executable($obj, $this);
572
+ if ($result instanceof $normalizedClass) {
573
+ $obj = $result;
574
+ }
575
+ }
576
+
577
+ $interfaces = @class_implements($obj);
578
+
579
+ if ($interfaces === false) {
580
+ throw new InjectionException(
581
+ $this->inProgressMakes,
582
+ sprintf(
583
+ self::M_MAKING_FAILED,
584
+ $normalizedClass,
585
+ gettype($obj)
586
+ ),
587
+ self::E_MAKING_FAILED
588
+ );
589
+ }
590
+
591
+ if (empty($interfaces)) {
592
+ return $obj;
593
+ }
594
+
595
+ $interfaces = array_flip(array_map(array($this, 'normalizeName'), $interfaces));
596
+ $prepares = array_intersect_key($this->prepares, $interfaces);
597
+ foreach ($prepares as $interfaceName => $prepare) {
598
+ $executable = $this->buildExecutable($prepare);
599
+ $result = $executable($obj, $this);
600
+ if ($result instanceof $normalizedClass) {
601
+ $obj = $result;
602
+ }
603
+ }
604
+
605
+ return $obj;
606
+ }
607
+
608
+ /**
609
+ * Invoke the specified callable or class::method string, provisioning dependencies along the way
610
+ *
611
+ * @param mixed $callableOrMethodStr A valid PHP callable or a provisionable ClassName::methodName string
612
+ * @param array $args Optional array specifying params with which to invoke the provisioned callable
613
+ * @throws \Auryn\InjectionException
614
+ * @return mixed Returns the invocation result returned from calling the generated executable
615
+ */
616
+ public function execute($callableOrMethodStr, array $args = array())
617
+ {
618
+ list($reflFunc, $invocationObj) = $this->buildExecutableStruct($callableOrMethodStr);
619
+ $executable = new Executable($reflFunc, $invocationObj);
620
+ $args = $this->provisionFuncArgs($reflFunc, $args);
621
+
622
+ return call_user_func_array(array($executable, '__invoke'), $args);
623
+ }
624
+
625
+ /**
626
+ * Provision an Executable instance from any valid callable or class::method string
627
+ *
628
+ * @param mixed $callableOrMethodStr A valid PHP callable or a provisionable ClassName::methodName string
629
+ * @return \Auryn\Executable
630
+ */
631
+ public function buildExecutable($callableOrMethodStr)
632
+ {
633
+ try {
634
+ list($reflFunc, $invocationObj) = $this->buildExecutableStruct($callableOrMethodStr);
635
+ } catch (\ReflectionException $e) {
636
+ throw InjectionException::fromInvalidCallable(
637
+ $this->inProgressMakes,
638
+ $callableOrMethodStr,
639
+ $e
640
+ );
641
+ }
642
+
643
+ return new Executable($reflFunc, $invocationObj);
644
+ }
645
+
646
+ private function buildExecutableStruct($callableOrMethodStr)
647
+ {
648
+ if (is_string($callableOrMethodStr)) {
649
+ $executableStruct = $this->buildExecutableStructFromString($callableOrMethodStr);
650
+ } elseif ($callableOrMethodStr instanceof \Closure) {
651
+ $callableRefl = new \ReflectionFunction($callableOrMethodStr);
652
+ $executableStruct = array($callableRefl, null);
653
+ } elseif (is_object($callableOrMethodStr) && is_callable($callableOrMethodStr)) {
654
+ $invocationObj = $callableOrMethodStr;
655
+ $callableRefl = $this->reflector->getMethod($invocationObj, '__invoke');
656
+ $executableStruct = array($callableRefl, $invocationObj);
657
+ } elseif (is_array($callableOrMethodStr)
658
+ && isset($callableOrMethodStr[0], $callableOrMethodStr[1])
659
+ && count($callableOrMethodStr) === 2
660
+ ) {
661
+ $executableStruct = $this->buildExecutableStructFromArray($callableOrMethodStr);
662
+ } else {
663
+ throw InjectionException::fromInvalidCallable(
664
+ $this->inProgressMakes,
665
+ $callableOrMethodStr
666
+ );
667
+ }
668
+
669
+ return $executableStruct;
670
+ }
671
+
672
+ private function buildExecutableStructFromString($stringExecutable)
673
+ {
674
+ if (function_exists($stringExecutable)) {
675
+ $callableRefl = $this->reflector->getFunction($stringExecutable);
676
+ $executableStruct = array($callableRefl, null);
677
+ } elseif (method_exists($stringExecutable, '__invoke')) {
678
+ $invocationObj = $this->make($stringExecutable);
679
+ $callableRefl = $this->reflector->getMethod($invocationObj, '__invoke');
680
+ $executableStruct = array($callableRefl, $invocationObj);
681
+ } elseif (strpos($stringExecutable, '::') !== false) {
682
+ list($class, $method) = explode('::', $stringExecutable, 2);
683
+ $executableStruct = $this->buildStringClassMethodCallable($class, $method);
684
+ } else {
685
+ throw InjectionException::fromInvalidCallable(
686
+ $this->inProgressMakes,
687
+ $stringExecutable
688
+ );
689
+ }
690
+
691
+ return $executableStruct;
692
+ }
693
+
694
+ private function buildStringClassMethodCallable($class, $method)
695
+ {
696
+ $relativeStaticMethodStartPos = strpos($method, 'parent::');
697
+
698
+ if ($relativeStaticMethodStartPos === 0) {
699
+ $childReflection = $this->reflector->getClass($class);
700
+ $class = $childReflection->getParentClass()->name;
701
+ $method = substr($method, $relativeStaticMethodStartPos + 8);
702
+ }
703
+
704
+ list($className, $normalizedClass) = $this->resolveAlias($class);
705
+ $reflectionMethod = $this->reflector->getMethod($className, $method);
706
+
707
+ if ($reflectionMethod->isStatic()) {
708
+ return array($reflectionMethod, null);
709
+ }
710
+
711
+ $instance = $this->make($className);
712
+ // If the class was delegated, the instance may not be of the type
713
+ // $class but some other type. We need to get the reflection on the
714
+ // actual class to be able to call the method correctly.
715
+ $reflectionMethod = $this->reflector->getMethod($instance, $method);
716
+
717
+ return array($reflectionMethod, $instance);
718
+ }
719
+
720
+ private function buildExecutableStructFromArray($arrayExecutable)
721
+ {
722
+ list($classOrObj, $method) = $arrayExecutable;
723
+
724
+ if (is_object($classOrObj) && method_exists($classOrObj, $method)) {
725
+ $callableRefl = $this->reflector->getMethod($classOrObj, $method);
726
+ $executableStruct = array($callableRefl, $classOrObj);
727
+ } elseif (is_string($classOrObj)) {
728
+ $executableStruct = $this->buildStringClassMethodCallable($classOrObj, $method);
729
+ } else {
730
+ throw InjectionException::fromInvalidCallable(
731
+ $this->inProgressMakes,
732
+ $arrayExecutable
733
+ );
734
+ }
735
+
736
+ return $executableStruct;
737
+ }
738
+ }
vendor/rdlowrey/auryn/lib/InjectorException.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class InjectorException extends \Exception
6
+ {
7
+ }
vendor/rdlowrey/auryn/lib/ReflectionCache.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ interface ReflectionCache
6
+ {
7
+ public function fetch($key);
8
+ public function store($key, $data);
9
+ }
vendor/rdlowrey/auryn/lib/ReflectionCacheApc.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class ReflectionCacheApc implements ReflectionCache
6
+ {
7
+ private $localCache;
8
+ private $timeToLive = 5;
9
+
10
+ public function __construct(ReflectionCache $localCache = null)
11
+ {
12
+ $this->localCache = $localCache ?: new ReflectionCacheArray;
13
+ }
14
+
15
+ public function setTimeToLive($seconds)
16
+ {
17
+ $seconds = (int) $seconds;
18
+ $this->timeToLive = ($seconds > 0) ? $seconds : $this->timeToLive;
19
+
20
+ return $this;
21
+ }
22
+
23
+ public function fetch($key)
24
+ {
25
+ $localData = $this->localCache->fetch($key);
26
+
27
+ if ($localData != false) {
28
+ return $localData;
29
+ } else {
30
+ $success = null; // stupid by-ref parameter that scrutinizer complains about
31
+ $data = apc_fetch($key, $success);
32
+ return $success ? $data : false;
33
+ }
34
+ }
35
+
36
+ public function store($key, $data)
37
+ {
38
+ $this->localCache->store($key, $data);
39
+ apc_store($key, $data, $this->timeToLive);
40
+ }
41
+ }
vendor/rdlowrey/auryn/lib/ReflectionCacheArray.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class ReflectionCacheArray implements ReflectionCache
6
+ {
7
+ private $cache = array();
8
+
9
+ public function fetch($key)
10
+ {
11
+ // The additional isset() check here improves performance but we also
12
+ // need array_key_exists() because some cached values === NULL.
13
+ return (isset($this->cache[$key]) || array_key_exists($key, $this->cache))
14
+ ? $this->cache[$key]
15
+ : false;
16
+ }
17
+
18
+ public function store($key, $data)
19
+ {
20
+ $this->cache[$key] = $data;
21
+ }
22
+ }
vendor/rdlowrey/auryn/lib/Reflector.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ interface Reflector
6
+ {
7
+ /**
8
+ * Retrieves ReflectionClass instances, caching them for future retrieval
9
+ *
10
+ * @param string $class
11
+ * @return \ReflectionClass
12
+ */
13
+ public function getClass($class);
14
+
15
+ /**
16
+ * Retrieves and caches the constructor (ReflectionMethod) for the specified class
17
+ *
18
+ * @param string $class
19
+ * @return \ReflectionMethod
20
+ */
21
+ public function getCtor($class);
22
+
23
+ /**
24
+ * Retrieves and caches an array of constructor parameters for the given class
25
+ *
26
+ * @param string $class
27
+ * @return \ReflectionParameter[]
28
+ */
29
+ public function getCtorParams($class);
30
+
31
+ /**
32
+ * Retrieves the class type-hint from a given ReflectionParameter
33
+ *
34
+ * There is no way to directly access a parameter's type-hint without
35
+ * instantiating a new ReflectionClass instance and calling its getName()
36
+ * method. This method stores the results of this approach so that if
37
+ * the same parameter type-hint or ReflectionClass is needed again we
38
+ * already have it cached.
39
+ *
40
+ * @param \ReflectionFunctionAbstract $function
41
+ * @param \ReflectionParameter $param
42
+ */
43
+ public function getParamTypeHint(\ReflectionFunctionAbstract $function, \ReflectionParameter $param);
44
+
45
+ /**
46
+ * Retrieves and caches a reflection for the specified function
47
+ *
48
+ * @param string $functionName
49
+ * @return \ReflectionFunction
50
+ */
51
+ public function getFunction($functionName);
52
+
53
+ /**
54
+ * Retrieves and caches a reflection for the specified class method
55
+ *
56
+ * @param mixed $classNameOrInstance
57
+ * @param string $methodName
58
+ * @return \ReflectionMethod
59
+ */
60
+ public function getMethod($classNameOrInstance, $methodName);
61
+ }
vendor/rdlowrey/auryn/lib/StandardReflector.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn;
4
+
5
+ class StandardReflector implements Reflector
6
+ {
7
+ public function getClass($class)
8
+ {
9
+ return new \ReflectionClass($class);
10
+ }
11
+
12
+ public function getCtor($class)
13
+ {
14
+ $reflectionClass = new \ReflectionClass($class);
15
+
16
+ return $reflectionClass->getConstructor();
17
+ }
18
+
19
+ public function getCtorParams($class)
20
+ {
21
+ return ($reflectedCtor = $this->getCtor($class))
22
+ ? $reflectedCtor->getParameters()
23
+ : null;
24
+ }
25
+
26
+ public function getParamTypeHint(\ReflectionFunctionAbstract $function, \ReflectionParameter $param)
27
+ {
28
+ return ($reflectionClass = $param->getClass())
29
+ ? $reflectionClass->getName()
30
+ : null;
31
+ }
32
+
33
+ public function getFunction($functionName)
34
+ {
35
+ return new \ReflectionFunction($functionName);
36
+ }
37
+
38
+ public function getMethod($classNameOrInstance, $methodName)
39
+ {
40
+ $className = is_string($classNameOrInstance)
41
+ ? $classNameOrInstance
42
+ : get_class($classNameOrInstance);
43
+
44
+ return new \ReflectionMethod($className, $methodName);
45
+ }
46
+ }
vendor/rdlowrey/auryn/phpunit.xml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit backupGlobals="false"
2
+ backupStaticAttributes="false"
3
+ colors="true"
4
+ convertErrorsToExceptions="true"
5
+ convertNoticesToExceptions="true"
6
+ convertWarningsToExceptions="true"
7
+ processIsolation="false"
8
+ stopOnFailure="false"
9
+ syntaxCheck="false"
10
+ bootstrap="vendor/autoload.php"
11
+ >
12
+ <testsuites>
13
+ <testsuite name="Unit-Tests">
14
+ <directory>./test</directory>
15
+ </testsuite>
16
+ </testsuites>
17
+ <filter>
18
+ <whitelist addUncoveredFilesFromWhitelist="true">
19
+ <directory>./lib</directory>
20
+ </whitelist>
21
+ </filter>
22
+
23
+ <logging>
24
+ <log
25
+ type="coverage-text"
26
+ target="php://stdout"
27
+ lowUpperBound="35"
28
+ highLowerBound="75"
29
+ />
30
+ <!-- uncomment below to generate HTML code coverage reports in ./test/coverage -->
31
+ <!--
32
+ <log
33
+ type="coverage-html"
34
+ target="./test/coverage"
35
+ charset="UTF-8"
36
+ yui="true"
37
+ lowUpperBound="35"
38
+ highLowerBound="70"
39
+ showUncoveredFiles="true"
40
+ />
41
+ -->
42
+ </logging>
43
+ </phpunit>
vendor/rdlowrey/auryn/test/Benchmark/ExecuteBenchmark.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn\Test\Benchmark;
4
+
5
+ use Athletic\AthleticEvent;
6
+ use Auryn\Injector;
7
+
8
+ class ExecuteBenchmark extends AthleticEvent
9
+ {
10
+ private $injector;
11
+ private $noop;
12
+
13
+ public function classSetUp()
14
+ {
15
+ $this->injector = new Injector();
16
+ $this->noop = new Noop();
17
+ }
18
+
19
+ /**
20
+ * @baseline
21
+ * @iterations 10000
22
+ */
23
+ public function native_invoke_closure()
24
+ {
25
+ call_user_func(function () {
26
+ // call-target, intenionally left empty
27
+ });
28
+ }
29
+
30
+ /**
31
+ * @iterations 10000
32
+ */
33
+ public function native_invoke_method()
34
+ {
35
+ call_user_func(array($this->noop, 'noop'));
36
+ }
37
+
38
+ /**
39
+ * @iterations 10000
40
+ */
41
+ public function invoke_closure()
42
+ {
43
+ $this->injector->execute(function () {
44
+ // call-target, intenionally left empty
45
+ });
46
+ }
47
+
48
+ /**
49
+ * @iterations 10000
50
+ */
51
+ public function invoke_method()
52
+ {
53
+ $this->injector->execute(array($this->noop, 'noop'));
54
+ }
55
+
56
+ /**
57
+ * @iterations 10000
58
+ */
59
+ public function invoke_with_named_parameters()
60
+ {
61
+ $this->injector->execute(array($this->noop, 'namedNoop'), array(':name' => 'foo'));
62
+ }
63
+ }
vendor/rdlowrey/auryn/test/Benchmark/Noop.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn\Test\Benchmark;
4
+
5
+ class Noop
6
+ {
7
+ public function noop()
8
+ {
9
+ // call-target, intenionally left empty
10
+ }
11
+
12
+ public function namedNoop($name)
13
+ {
14
+ // call-target, intenionally left empty
15
+ }
16
+
17
+ public function typehintedNoop(noop $noop)
18
+ {
19
+ // call-target, intenionally left empty
20
+ }
21
+ }
vendor/rdlowrey/auryn/test/InjectorTest.php ADDED
@@ -0,0 +1,1107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Auryn\test;
4
+
5
+ use Auryn\Injector;
6
+
7
+ class InjectorTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ public function testMakeInstanceInjectsSimpleConcreteDependency()
10
+ {
11
+ $injector = new Injector;
12
+ $this->assertEquals(new TestNeedsDep(new TestDependency),
13
+ $injector->make('Auryn\Test\TestNeedsDep')
14
+ );
15
+ }
16
+
17
+ public function testMakeInstanceReturnsNewInstanceIfClassHasNoConstructor()
18
+ {
19
+ $injector = new Injector;
20
+ $this->assertEquals(new TestNoConstructor, $injector->make('Auryn\Test\TestNoConstructor'));
21
+ }
22
+
23
+ public function testMakeInstanceReturnsAliasInstanceOnNonConcreteTypehint()
24
+ {
25
+ $injector = new Injector;
26
+ $injector->alias('Auryn\Test\DepInterface', 'Auryn\Test\DepImplementation');
27
+ $this->assertEquals(new DepImplementation, $injector->make('Auryn\Test\DepInterface'));
28
+ }
29
+
30
+ /**
31
+ * @expectedException \Auryn\InjectionException
32
+ * @expectedExceptionCode \Auryn\Injector::E_NEEDS_DEFINITION
33
+ */
34
+ public function testMakeInstanceThrowsExceptionOnInterfaceWithoutAlias()
35
+ {
36
+ $injector = new Injector;
37
+ $injector->make('Auryn\Test\DepInterface');
38
+ }
39
+
40
+ /**
41
+ * @expectedException \Auryn\InjectionException
42
+ * @expectedExceptionCode \Auryn\Injector::E_NEEDS_DEFINITION
43
+ */
44
+ public function testMakeInstanceThrowsExceptionOnNonConcreteCtorParamWithoutImplementation()
45
+ {
46
+ $injector = new Injector;
47
+ $injector->make('Auryn\Test\RequiresInterface');
48
+ }
49
+
50
+ public function testMakeInstanceBuildsNonConcreteCtorParamWithAlias()
51
+ {
52
+ $injector = new Injector;
53
+ $injector->alias('Auryn\Test\DepInterface', 'Auryn\Test\DepImplementation');
54
+ $obj = $injector->make('Auryn\Test\RequiresInterface');
55
+ $this->assertInstanceOf('Auryn\Test\RequiresInterface', $obj);
56
+ }
57
+
58
+ public function testMakeInstancePassesNullCtorParameterIfNoTypehintOrDefaultCanBeDetermined()
59
+ {
60
+ $injector = new Injector;
61
+ $nullCtorParamObj = $injector->make('Auryn\Test\ProvTestNoDefinitionNullDefaultClass');
62
+ $this->assertEquals(new ProvTestNoDefinitionNullDefaultClass, $nullCtorParamObj);
63
+ $this->assertEquals(null, $nullCtorParamObj->arg);
64
+ }
65
+
66
+ public function testMakeInstanceReturnsSharedInstanceIfAvailable()
67
+ {
68
+ $injector = new Injector;
69
+ $injector->define('Auryn\Test\RequiresInterface', array('dep' => 'Auryn\Test\DepImplementation'));
70
+ $injector->share('Auryn\Test\RequiresInterface');
71
+ $injected = $injector->make('Auryn\Test\RequiresInterface');
72
+
73
+ $this->assertEquals('something', $injected->testDep->testProp);
74
+ $injected->testDep->testProp = 'something else';
75
+
76
+ $injected2 = $injector->make('Auryn\Test\RequiresInterface');
77
+ $this->assertEquals('something else', $injected2->testDep->testProp);
78
+ }
79
+
80
+ /**
81
+ * @expectedException Auryn\InjectorException
82
+ */
83
+ public function testMakeInstanceThrowsExceptionOnClassLoadFailure()
84
+ {
85
+ $injector = new Injector;
86
+ $injector->make('ClassThatDoesntExist');
87
+ }
88
+
89
+ public function testMakeInstanceUsesCustomDefinitionIfSpecified()
90
+ {
91
+ $injector = new Injector;
92
+ $injector->define('Auryn\Test\TestNeedsDep', array('testDep'=>'Auryn\Test\TestDependency'));
93
+ $injected = $injector->make('Auryn\Test\TestNeedsDep', array('testDep'=>'Auryn\Test\TestDependency2'));
94
+ $this->assertEquals('testVal2', $injected->testDep->testProp);
95
+ }
96
+
97
+ public function testMakeInstanceCustomDefinitionOverridesExistingDefinitions()
98
+ {
99
+ $injector = new Injector;
100
+ $injector->define('Auryn\Test\InjectorTestChildClass', array(':arg1'=>'First argument', ':arg2'=>'Second argument'));
101
+ $injected = $injector->make('Auryn\Test\InjectorTestChildClass', array(':arg1'=>'Override'));
102
+ $this->assertEquals('Override', $injected->arg1);
103
+ $this->assertEquals('Second argument', $injected->arg2);
104
+ }
105
+
106
+ public function testMakeInstanceStoresShareIfMarkedWithNullInstance()
107
+ {
108
+ $injector = new Injector;
109
+ $injector->share('Auryn\Test\TestDependency');
110
+ $injector->make('Auryn\Test\TestDependency');
111
+ }
112
+
113
+ public function testMakeInstanceUsesReflectionForUnknownParamsInMultiBuildWithDeps()
114
+ {
115
+ $injector = new Injector;
116
+ $obj = $injector->make('Auryn\Test\TestMultiDepsWithCtor', array('val1'=>'Auryn\Test\TestDependency'));
117
+ $this->assertInstanceOf('Auryn\Test\TestMultiDepsWithCtor', $obj);
118
+
119
+ $obj = $injector->make('Auryn\Test\NoTypehintNoDefaultConstructorClass',
120
+ array('val1'=>'Auryn\Test\TestDependency')
121
+ );
122
+ $this->assertInstanceOf('Auryn\Test\NoTypehintNoDefaultConstructorClass', $obj);
123
+ $this->assertEquals(null, $obj->testParam);
124
+ }
125
+
126
+ /**
127
+ * @expectedException \Auryn\InjectionException
128
+ * @expectedExceptionCode \Auryn\Injector::E_UNDEFINED_PARAM
129
+ */
130
+ public function testMakeInstanceThrowsExceptionOnUntypehintedParameterWithoutDefinitionOrDefault()
131
+ {
132
+ $injector = new Injector;
133
+ $obj = $injector->make('Auryn\Test\InjectorTestCtorParamWithNoTypehintOrDefault');
134
+ $this->assertNull($obj->val);
135
+ }
136
+
137
+ /**
138
+ * @expectedException \Auryn\InjectionException
139
+ * @expectedExceptionCode \Auryn\Injector::E_UNDEFINED_PARAM
140
+ */
141
+ public function testMakeInstanceThrowsExceptionOnUntypehintedParameterWithoutDefinitionOrDefaultThroughAliasedTypehint()
142
+ {
143
+ $injector = new Injector;
144
+ $injector->alias('Auryn\Test\TestNoExplicitDefine', 'Auryn\Test\InjectorTestCtorParamWithNoTypehintOrDefault');
145
+ $injector->make('Auryn\Test\InjectorTestCtorParamWithNoTypehintOrDefaultDependent');
146
+ }
147
+
148
+ /**
149
+ * @TODO
150
+ * @expectedException Auryn\InjectorException
151
+ */
152
+ public function testMakeInstanceThrowsExceptionOnUninstantiableTypehintWithoutDefinition()
153
+ {
154
+ $injector = new Injector;
155
+ $obj = $injector->make('Auryn\Test\RequiresInterface');
156
+ }
157
+
158
+ public function testTypelessDefineForDependency()
159
+ {
160
+ $thumbnailSize = 128;
161
+ $injector = new Injector;
162
+ $injector->defineParam('thumbnailSize', $thumbnailSize);
163
+ $testClass = $injector->make('Auryn\Test\RequiresDependencyWithTypelessParameters');
164
+ $this->assertEquals($thumbnailSize, $testClass->getThumbnailSize(), 'Typeless define was not injected correctly.');
165
+ }
166
+
167
+ public function testTypelessDefineForAliasedDependency()
168
+ {
169
+ $injector = new Injector;
170
+ $injector->defineParam('val', 42);
171
+
172
+ $injector->alias('Auryn\Test\TestNoExplicitDefine', 'Auryn\Test\ProviderTestCtorParamWithNoTypehintOrDefault');
173
+ $obj = $injector->make('Auryn\Test\ProviderTestCtorParamWithNoTypehintOrDefaultDependent');
174
+ }
175
+
176
+ public function testMakeInstanceInjectsRawParametersDirectly()
177
+ {
178
+ $injector = new Injector;
179
+ $injector->define('Auryn\Test\InjectorTestRawCtorParams', array(
180
+ ':string' => 'string',
181
+ ':obj' => new \StdClass,
182
+ ':int' => 42,
183
+ ':array' => array(),
184
+ ':float' => 9.3,
185
+ ':bool' => true,
186
+ ':null' => null,
187
+ ));
188
+
189
+ $obj = $injector->make('Auryn\Test\InjectorTestRawCtorParams');
190
+ $this->assertInternalType('string', $obj->string);
191
+ $this->assertInstanceOf('StdClass', $obj->obj);
192
+ $this->assertInternalType('int', $obj->int);
193
+ $this->assertInternalType('array', $obj->array);
194
+ $this->assertInternalType('float', $obj->float);
195
+ $this->assertInternalType('bool', $obj->bool);
196
+ $this->assertNull($obj->null);
197
+ }
198
+
199
+ /**
200
+ * @TODO
201
+ * @