Shortcode in Menus - Version 3.2

Version Description

  • Code Refactoring
  • Changed tested upto
  • Corrected links in description
Download this release

Release Info

Developer gagan0123
Plugin Icon 128x128 Shortcode in Menus
Version 3.2
Comparing to
See all releases

Code changes from version 3.1 to 3.2

includes/class-shortcode-in-menus.php ADDED
@@ -0,0 +1,385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // If this file is called directly, abort.
3
+ if ( !defined( 'ABSPATH' ) )
4
+ exit; // Exit if accessed directly
5
+
6
+
7
+ if ( !class_exists( 'Shortcode_In_Menus' ) ) {
8
+
9
+ class Shortcode_In_Menus {
10
+
11
+ protected static $instance = null;
12
+
13
+ /**
14
+ * @return Barebone Returns the current instance of the class
15
+ */
16
+ public static function get_instance() {
17
+
18
+ // If the single instance hasn't been set, set it now.
19
+ if ( null == self::$instance ) {
20
+ self::$instance = new self;
21
+ }
22
+
23
+ return self::$instance;
24
+ }
25
+
26
+ /**
27
+ * Hooks, filters and registers everything appropriately
28
+ */
29
+ public function __construct() {
30
+
31
+ // register a test shortcode for testing
32
+ add_shortcode( 'gs_test_shortcode', array( $this, 'shortcode' ) );
33
+
34
+ // setup the meta box
35
+ add_action( 'admin_init', array( $this, 'setup_meta_box' ) );
36
+
37
+ // filter the menu item output on frontend
38
+ add_filter( 'walker_nav_menu_start_el', array( $this, 'start_el' ), 10, 2 );
39
+
40
+ // filter the menu item before display in admin
41
+ add_filter( 'wp_setup_nav_menu_item', array( $this, 'setup_item' ), 10, 1 );
42
+
43
+ // enqueue custom js
44
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
45
+
46
+ // add an ajax hack to save the html content
47
+ add_action( 'wp_ajax_gs_sim_description_hack', array( $this, 'description_hack' ) );
48
+
49
+ // hook to allow saving of shortcode in custom link metabox for legacy support
50
+ add_action( 'wp_loaded', array( $this, 'security_check' ) );
51
+
52
+ // filter the output when shortcode is saved using custom links, for legacy support
53
+ add_filter( 'clean_url', array( $this, 'display_shortcode' ), 1, 3 );
54
+
55
+ add_action( 'wp_ajax_add-menu-item', array( $this, 'ajax_add_menu_item' ), 0 );
56
+ }
57
+
58
+ /**
59
+ * Test shortcode. Output's the developer's url
60
+ *
61
+ * @return string
62
+ */
63
+ public function shortcode() {
64
+ return "http://gagan.pro";
65
+ }
66
+
67
+ /**
68
+ * Gets a new object id,given the current one
69
+ *
70
+ * @param int $last_object_id The current/last object id
71
+ * @return int
72
+ */
73
+ public function new_object_id( $last_object_id ) {
74
+
75
+ // make sure it's an integer
76
+ $object_id = (int) $last_object_id;
77
+
78
+ // increment it
79
+ $object_id++;
80
+
81
+ // if object_id was 0 to start off with, make it 1
82
+ $object_id = ($object_id < 1) ? 1 : $object_id;
83
+
84
+ // save into the options table
85
+ update_option( 'gs_sim_last_object_id', $object_id );
86
+
87
+ return $object_id;
88
+ }
89
+
90
+ /**
91
+ * Register our custom meta box
92
+ */
93
+ public function setup_meta_box() {
94
+ add_meta_box( 'add-shortcode-section', __( 'Shortcode' ), array( $this, 'meta_box' ), 'nav-menus', 'side', 'default' );
95
+ }
96
+
97
+ /**
98
+ * Display our custom meta box
99
+ * @global int $_nav_menu_placeholder A placeholder index for the menu item
100
+ * @global int|string $nav_menu_selected_id (id, name or slug) of the currently-selected menu
101
+ */
102
+ public function meta_box() {
103
+ global $_nav_menu_placeholder, $nav_menu_selected_id;
104
+
105
+ $_nav_menu_placeholder = 0 > $_nav_menu_placeholder ? $_nav_menu_placeholder - 1 : -1;
106
+
107
+ $last_object_id = get_option( 'gs_sim_last_object_id', 0 );
108
+ $object_id = $this->new_object_id( $last_object_id );
109
+ ?>
110
+ <div class="gs-sim-div" id="gs-sim-div">
111
+ <input type="hidden" class="menu-item-db-id" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-db-id]" value="0" />
112
+ <input type="hidden" class="menu-item-object-id" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-object-id]" value="<?php echo $object_id; ?>" />
113
+ <input type="hidden" class="menu-item-object" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-object]" value="gs_sim" />
114
+ <input type="hidden" class="menu-item-type" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-type]" value="gs_sim" />
115
+ <input type="hidden" id="gs-sim-description-nonce" value="<?php echo wp_create_nonce( 'gs-sim-description-nonce' ) ?>" />
116
+ <p id="menu-item-title-wrap">
117
+ <label for="gs-sim-title"><?php _e( 'Title' ); ?></label>
118
+ <input id="gs-sim-title" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox" title="<?php esc_attr_e( 'Title' ); ?>" style="width:100%" />
119
+ </p>
120
+
121
+ <p id="menu-item-html-wrap">
122
+ <textarea style="width:100%;" rows="9" id="gs-sim-html" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-description]" class="code menu-item-textbox" title="<?php esc_attr_e( 'Text/HTML/shortcode here!', 'shortcode-in-menus' ); ?>"></textarea>
123
+ </p>
124
+
125
+ <p class="button-controls">
126
+ <span class="add-to-menu">
127
+ <input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to Menu' ); ?>" name="add-gs-sim-menu-item" id="submit-gs-sim" />
128
+ <span class="spinner"></span>
129
+ </span>
130
+ </p>
131
+
132
+ </div>
133
+ <?php
134
+ }
135
+
136
+ /**
137
+ * Check if the passed content has any shortcode. Inspired from the core's has_shortcode
138
+ *
139
+ * @param string $content The content to check for shortcode
140
+ * @return boolean
141
+ * @author Saurabh Shukla
142
+ */
143
+ function has_shortcode( $content ) {
144
+
145
+ if ( false !== strpos( $content, '[' ) ) {
146
+
147
+ preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER );
148
+
149
+ if ( !empty( $matches ) ) {
150
+ return true;
151
+ }
152
+ }
153
+ return false;
154
+ }
155
+
156
+ /**
157
+ * Modifies the menu item display on frontend
158
+ *
159
+ * @param string $item_output The original html.
160
+ * @param object $item The menu item being displayed.
161
+ * @return object
162
+ */
163
+ public function start_el( $item_output, $item ) {
164
+ // if it isn't our custom object
165
+ if ( $item->object != 'gs_sim' ) {
166
+
167
+ // check the legacy hack
168
+ if ( $item->post_title == 'FULL HTML OUTPUT' ) {
169
+
170
+ // then just process as we used to
171
+ $item_output = do_shortcode( $item->url );
172
+ } else {
173
+ $item_output = do_shortcode( $item_output );
174
+ }
175
+
176
+ // if it is our object
177
+ } else {
178
+ // just process it
179
+ $item_output = do_shortcode( $item->description );
180
+ }
181
+
182
+ return $item_output;
183
+ }
184
+
185
+ /**
186
+ * Modify the menu item before display on Menu editor
187
+ *
188
+ * @param object $item The menu item
189
+ * @return object
190
+ */
191
+ public function setup_item( $item ) {
192
+ if ( !is_object( $item ) )
193
+ return $item;
194
+
195
+ // only if it is our object
196
+ if ( $item->object == 'gs_sim' ) {
197
+
198
+ // setup our label
199
+ $item->type_label = __( 'Shortcode' );
200
+
201
+ if ( $item->post_content != '' ) {
202
+ $item->description = $item->post_content;
203
+ } else {
204
+
205
+ // set up the description from the transient
206
+ $item->description = get_transient( 'gs_sim_description_hack_' . $item->object_id );
207
+
208
+ // discard the transient
209
+ delete_transient( 'gs_sim_description_hack_' . $item->object_id );
210
+ }
211
+ }
212
+ return $item;
213
+ }
214
+
215
+ /**
216
+ * Enqueue our custom js
217
+ *
218
+ * @param string $hook The current screen
219
+ * @return null
220
+ */
221
+ public function enqueue( $hook ) {
222
+
223
+ // don't enqueue if it isn't the menu editor
224
+ if ( 'nav-menus.php' != $hook )
225
+ return;
226
+
227
+ // otherwise enqueue with nav-menu.js as a dependency so that our script is loaded after it
228
+ wp_enqueue_script(
229
+ 'gs-sim-admin', GS_SIM_URL . 'public/js/admin.js', array( 'nav-menu' )
230
+ );
231
+ }
232
+
233
+ /**
234
+ * An ajax based workaround to save descriptions without using the custom object type
235
+ */
236
+ public function description_hack() {
237
+ // verify the nonce
238
+ $nonce = $_POST[ 'description-nonce' ];
239
+ if ( !wp_verify_nonce( $nonce, 'gs-sim-description-nonce' ) ) {
240
+ die();
241
+ }
242
+
243
+ // get the menu item
244
+ $item = $_POST[ 'menu-item' ];
245
+
246
+ // save the description in a transient. This is what we'll use in setup_item()
247
+ set_transient( 'gs_sim_description_hack_' . $item[ 'menu-item-object-id' ], $item[ 'menu-item-description' ] );
248
+
249
+ // increment the object id, so it can be used by js
250
+ $object_id = $this->new_object_id( $item[ 'menu-item-object-id' ] );
251
+
252
+ echo $object_id;
253
+
254
+ die();
255
+ }
256
+
257
+ /**
258
+ * Legacy method to allow saving of shortcodes in custom_link url
259
+ *
260
+ * @deprecated since 2.0
261
+ *
262
+ * @param string $url The processed url for displaying/saving
263
+ * @param string $orig_url The url that was submitted, retreived
264
+ * @param string $context Whether saving or displaying
265
+ * @return string
266
+ */
267
+ public function save_shortcode( $url, $orig_url, $context ) {
268
+
269
+ if ( $context == 'db' && $this->has_shortcode( $orig_url ) ) {
270
+ return $orig_url;
271
+ }
272
+ return $url;
273
+ }
274
+
275
+ /**
276
+ * Allows shortcodes into the custom link url field
277
+ *
278
+ * @deprecated since 2.0
279
+ */
280
+ public function security_check() {
281
+ if ( current_user_can( 'activate_plugins' ) ) {
282
+ //Conditionally adding the function for database context for
283
+ add_filter( 'clean_url', array( $this, 'save_shortcode' ), 99, 3 );
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Allows shortcode to be processed and displayed
289
+ *
290
+ * @deprecated since 2.0
291
+ *
292
+ * @param string $url The processed url for displaying/saving
293
+ * @param string $orig_url The url that was submitted, retreived
294
+ * @param string $context Whether saving or displaying
295
+ * @return string
296
+ */
297
+ public function display_shortcode( $url, $orig_url, $context ) {
298
+ if ( $context == 'display' && $this->has_shortcode( $orig_url ) ) {
299
+ return do_shortcode( $orig_url );
300
+ }
301
+ return $url;
302
+ }
303
+
304
+ /**
305
+ * Ajax handler for add menu item request
306
+ */
307
+ public function ajax_add_menu_item() {
308
+
309
+ check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
310
+
311
+ if ( !current_user_can( 'edit_theme_options' ) ) {
312
+ wp_die( -1 );
313
+ }
314
+
315
+ require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
316
+
317
+ // For performance reasons, we omit some object properties from the checklist.
318
+ // The following is a hacky way to restore them when adding non-custom items.
319
+
320
+ $menu_items_data = array();
321
+ foreach ( (array) $_POST[ 'menu-item' ] as $menu_item_data ) {
322
+ if (
323
+ !empty( $menu_item_data[ 'menu-item-type' ] ) &&
324
+ 'custom' != $menu_item_data[ 'menu-item-type' ] &&
325
+ 'gs_sim' != $menu_item_data[ 'menu-item-type' ] &&
326
+ !empty( $menu_item_data[ 'menu-item-object-id' ] )
327
+ ) {
328
+ switch ( $menu_item_data[ 'menu-item-type' ] ) {
329
+ case 'post_type' :
330
+ $_object = get_post( $menu_item_data[ 'menu-item-object-id' ] );
331
+ break;
332
+
333
+ case 'taxonomy' :
334
+ $_object = get_term( $menu_item_data[ 'menu-item-object-id' ], $menu_item_data[ 'menu-item-object' ] );
335
+ break;
336
+ }
337
+
338
+ $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
339
+ $_menu_item = reset( $_menu_items );
340
+
341
+ // Restore the missing menu item properties
342
+ $menu_item_data[ 'menu-item-description' ] = $_menu_item->description;
343
+ }
344
+
345
+ $menu_items_data[] = $menu_item_data;
346
+ }
347
+
348
+ $item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
349
+ if ( is_wp_error( $item_ids ) )
350
+ wp_die( 0 );
351
+
352
+ $menu_items = array();
353
+
354
+ foreach ( (array) $item_ids as $menu_item_id ) {
355
+ $menu_obj = get_post( $menu_item_id );
356
+ if ( !empty( $menu_obj->ID ) ) {
357
+ $menu_obj = wp_setup_nav_menu_item( $menu_obj );
358
+ $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
359
+ $menu_items[] = $menu_obj;
360
+ }
361
+ }
362
+
363
+ /** This filter is documented in wp-admin/includes/nav-menu.php */
364
+ $walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $_POST[ 'menu' ] );
365
+
366
+ if ( !class_exists( $walker_class_name ) )
367
+ wp_die( 0 );
368
+
369
+ if ( !empty( $menu_items ) ) {
370
+ $args = array(
371
+ 'after' => '',
372
+ 'before' => '',
373
+ 'link_after' => '',
374
+ 'link_before' => '',
375
+ 'walker' => new $walker_class_name,
376
+ );
377
+ echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
378
+ }
379
+ wp_die();
380
+ }
381
+
382
+ }
383
+
384
+ Shortcode_In_Menus::get_instance();
385
+ }
index.php CHANGED
@@ -1,378 +1,3 @@
1
  <?php
2
- /*
3
- Plugin Name: Shortcodes in Menus
4
- Description: Allows you to add shortcodes in WordPress Navigation Menus
5
- Plugin URI: http://wordpress.org/plugins/shortcode-in-menus/
6
- Version: 3.1
7
- Author: <a href="http://gagan.pro">Gagan Deep Singh</a> and <a href="http://hookrefineandtinker.com">Saurabh Shukla</a>
8
- Text Domain: shortcode-in-menus
9
- */
10
-
11
- if ( !defined( 'ABSPATH' ) )
12
- exit; // Exit if accessed directly
13
-
14
- if ( !class_exists( 'gsShortCodeInMenu' ) ) {
15
-
16
- class gsShortCodeInMenu {
17
-
18
- /**
19
- * Hooks, filters and registers everything appropriately
20
- */
21
- public function init() {
22
-
23
- // register a test shortcode for testing
24
- add_shortcode( 'gs_test_shortcode', array( $this, 'shortcode' ) );
25
-
26
- // setup the meta box
27
- add_action( 'admin_init', array( $this, 'setup_meta_box' ) );
28
-
29
- // filter the menu item output on frontend
30
- add_filter( 'walker_nav_menu_start_el', array( $this, 'start_el' ), 10, 2 );
31
-
32
- // filter the menu item before display in admin
33
- add_filter( 'wp_setup_nav_menu_item', array( $this, 'setup_item' ), 10, 1 );
34
-
35
- // enqueue custom js
36
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
37
-
38
- // add an ajax hack to save the html content
39
- add_action( 'wp_ajax_gs_sim_description_hack', array( $this, 'description_hack' ) );
40
-
41
- // hook to allow saving of shortcode in custom link metabox for legacy support
42
- add_action( 'wp_loaded', array( $this, 'security_check' ) );
43
-
44
- // filter the output when shortcode is saved using custom links, for legacy support
45
- add_filter( 'clean_url', array( $this, 'display_shortcode' ), 1, 3 );
46
-
47
- add_action( 'wp_ajax_add-menu-item', array( $this, 'ajax_add_menu_item' ), 0 );
48
- }
49
-
50
- /**
51
- * Test shortcode. Output's the developer's url
52
- *
53
- * @return string
54
- */
55
- public function shortcode() {
56
- return "http://gagan.pro";
57
- }
58
-
59
- /**
60
- * Gets a new object id,given the current one
61
- *
62
- * @param int $last_object_id The current/last object id
63
- * @return int
64
- */
65
- public function new_object_id( $last_object_id ) {
66
-
67
- // make sure it's an integer
68
- $object_id = (int) $last_object_id;
69
-
70
- // increment it
71
- $object_id++;
72
-
73
- // if object_id was 0 to start off with, make it 1
74
- $object_id = ($object_id < 1) ? 1 : $object_id;
75
-
76
- // save into the options table
77
- update_option( 'gs_sim_last_object_id', $object_id );
78
-
79
- return $object_id;
80
- }
81
-
82
- /**
83
- * Register our custom meta box
84
- */
85
- public function setup_meta_box() {
86
- add_meta_box( 'add-shortcode-section', __( 'Shortcode' ), array( $this, 'meta_box' ), 'nav-menus', 'side', 'default' );
87
- }
88
-
89
- /**
90
- * Display our custom meta box
91
- * @global int $_nav_menu_placeholder A placeholder index for the menu item
92
- * @global int|string $nav_menu_selected_id (id, name or slug) of the currently-selected menu
93
- */
94
- public function meta_box() {
95
- global $_nav_menu_placeholder, $nav_menu_selected_id;
96
-
97
- $_nav_menu_placeholder = 0 > $_nav_menu_placeholder ? $_nav_menu_placeholder - 1 : -1;
98
-
99
- $last_object_id = get_option( 'gs_sim_last_object_id', 0 );
100
- $object_id = $this->new_object_id( $last_object_id );
101
- ?>
102
- <div class="gs-sim-div" id="gs-sim-div">
103
- <input type="hidden" class="menu-item-db-id" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-db-id]" value="0" />
104
- <input type="hidden" class="menu-item-object-id" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-object-id]" value="<?php echo $object_id; ?>" />
105
- <input type="hidden" class="menu-item-object" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-object]" value="gs_sim" />
106
- <input type="hidden" class="menu-item-type" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-type]" value="gs_sim" />
107
- <input type="hidden" id="gs-sim-description-nonce" value="<?php echo wp_create_nonce( 'gs-sim-description-nonce' ) ?>" />
108
- <p id="menu-item-title-wrap">
109
- <label for="gs-sim-title"><?php _e( 'Title' ); ?></label>
110
- <input id="gs-sim-title" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox" title="<?php esc_attr_e( 'Title' ); ?>" style="width:100%" />
111
- </p>
112
-
113
- <p id="menu-item-html-wrap">
114
- <textarea style="width:100%;" rows="9" id="gs-sim-html" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-description]" class="code menu-item-textbox" title="<?php esc_attr_e( 'Text/HTML/shortcode here!' , 'shortcode-in-menus'); ?>"></textarea>
115
- </p>
116
-
117
- <p class="button-controls">
118
- <span class="add-to-menu">
119
- <input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to Menu' ); ?>" name="add-gs-sim-menu-item" id="submit-gs-sim" />
120
- <span class="spinner"></span>
121
- </span>
122
- </p>
123
-
124
- </div>
125
- <?php
126
- }
127
-
128
- /**
129
- * Check if the passed content has any shortcode. Inspired from the core's has_shortcode
130
- *
131
- * @param string $content The content to check for shortcode
132
- * @return boolean
133
- * @author Saurabh Shukla
134
- */
135
- function has_shortcode( $content ) {
136
-
137
- if ( false !== strpos( $content, '[' ) ) {
138
-
139
- preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER );
140
-
141
- if ( !empty( $matches ) ) {
142
- return true;
143
- }
144
- }
145
- return false;
146
- }
147
-
148
- /**
149
- * Modifies the menu item display on frontend
150
- *
151
- * @param string $item_output The original html.
152
- * @param object $item The menu item being displayed.
153
- * @return object
154
- */
155
- public function start_el( $item_output, $item ) {
156
- // if it isn't our custom object
157
- if ( $item->object != 'gs_sim' ) {
158
-
159
- // check the legacy hack
160
- if ( $item->post_title == 'FULL HTML OUTPUT' ) {
161
-
162
- // then just process as we used to
163
- $item_output = do_shortcode( $item->url );
164
- } else {
165
- $item_output = do_shortcode( $item_output );
166
- }
167
-
168
- // if it is our object
169
- } else {
170
- // just process it
171
- $item_output = do_shortcode( $item->description );
172
- }
173
-
174
- return $item_output;
175
- }
176
-
177
- /**
178
- * Modify the menu item before display on Menu editor
179
- *
180
- * @param object $item The menu item
181
- * @return object
182
- */
183
- public function setup_item( $item ) {
184
- if ( !is_object( $item ) )
185
- return $item;
186
-
187
- // only if it is our object
188
- if ( $item->object == 'gs_sim' ) {
189
-
190
- // setup our label
191
- $item->type_label = __( 'Shortcode' );
192
-
193
- if ( $item->post_content != '' ) {
194
- $item->description = $item->post_content;
195
- } else {
196
-
197
- // set up the description from the transient
198
- $item->description = get_transient( 'gs_sim_description_hack_' . $item->object_id );
199
-
200
- // discard the transient
201
- delete_transient( 'gs_sim_description_hack_' . $item->object_id );
202
- }
203
- }
204
- return $item;
205
- }
206
-
207
- /**
208
- * Enqueue our custom js
209
- *
210
- * @param string $hook The current screen
211
- * @return null
212
- */
213
- public function enqueue( $hook ) {
214
-
215
- // don't enqueue if it isn't the menu editor
216
- if ( 'nav-menus.php' != $hook )
217
- return;
218
-
219
- // otherwise enqueue with nav-menu.js as a dependency so that our script is loaded after it
220
- wp_enqueue_script(
221
- 'gs-sim-admin', plugins_url( '/js/admin.js', __FILE__ ), array( 'nav-menu' )
222
- );
223
- }
224
-
225
- /**
226
- * An ajax based workaround to save descriptions without using the custom object type
227
- */
228
- public function description_hack() {
229
- // verify the nonce
230
- $nonce = $_POST[ 'description-nonce' ];
231
- if ( !wp_verify_nonce( $nonce, 'gs-sim-description-nonce' ) ) {
232
- die();
233
- }
234
-
235
- // get the menu item
236
- $item = $_POST[ 'menu-item' ];
237
-
238
- // save the description in a transient. This is what we'll use in setup_item()
239
- set_transient( 'gs_sim_description_hack_' . $item[ 'menu-item-object-id' ], $item[ 'menu-item-description' ] );
240
-
241
- // increment the object id, so it can be used by js
242
- $object_id = $this->new_object_id( $item[ 'menu-item-object-id' ] );
243
-
244
- echo $object_id;
245
-
246
- die();
247
- }
248
-
249
- /**
250
- * Legacy method to allow saving of shortcodes in custom_link url
251
- *
252
- * @deprecated since 2.0
253
- *
254
- * @param string $url The processed url for displaying/saving
255
- * @param string $orig_url The url that was submitted, retreived
256
- * @param string $context Whether saving or displaying
257
- * @return string
258
- */
259
- public function save_shortcode( $url, $orig_url, $context ) {
260
-
261
- if ( $context == 'db' && $this->has_shortcode( $orig_url) ) {
262
- return $orig_url;
263
- }
264
- return $url;
265
- }
266
-
267
- /**
268
- * Allows shortcodes into the custom link url field
269
- *
270
- * @deprecated since 2.0
271
- */
272
- public function security_check() {
273
- if ( current_user_can( 'activate_plugins' ) ) {
274
- //Conditionally adding the function for database context for
275
- add_filter( 'clean_url', array( $this, 'save_shortcode' ), 99, 3 );
276
- }
277
- }
278
-
279
- /**
280
- * Allows shortcode to be processed and displayed
281
- *
282
- * @deprecated since 2.0
283
- *
284
- * @param string $url The processed url for displaying/saving
285
- * @param string $orig_url The url that was submitted, retreived
286
- * @param string $context Whether saving or displaying
287
- * @return string
288
- */
289
- public function display_shortcode( $url, $orig_url, $context ) {
290
- if ( $context == 'display' && $this->has_shortcode( $orig_url ) ) {
291
- return do_shortcode( $orig_url );
292
- }
293
- return $url;
294
- }
295
-
296
- /**
297
- * Ajax handler for add menu item request
298
- */
299
- public function ajax_add_menu_item() {
300
-
301
- check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
302
-
303
- if ( !current_user_can( 'edit_theme_options' ) )
304
- wp_die( -1 );
305
-
306
- require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
307
-
308
- // For performance reasons, we omit some object properties from the checklist.
309
- // The following is a hacky way to restore them when adding non-custom items.
310
-
311
- $menu_items_data = array();
312
- foreach ( (array) $_POST[ 'menu-item' ] as $menu_item_data ) {
313
- if (
314
- !empty( $menu_item_data[ 'menu-item-type' ] ) &&
315
- 'custom' != $menu_item_data[ 'menu-item-type' ] &&
316
- 'gs_sim' != $menu_item_data[ 'menu-item-type' ] &&
317
- !empty( $menu_item_data[ 'menu-item-object-id' ] )
318
- ) {
319
- switch ( $menu_item_data[ 'menu-item-type' ] ) {
320
- case 'post_type' :
321
- $_object = get_post( $menu_item_data[ 'menu-item-object-id' ] );
322
- break;
323
-
324
- case 'taxonomy' :
325
- $_object = get_term( $menu_item_data[ 'menu-item-object-id' ], $menu_item_data[ 'menu-item-object' ] );
326
- break;
327
- }
328
-
329
- $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
330
- $_menu_item = reset( $_menu_items );
331
-
332
- // Restore the missing menu item properties
333
- $menu_item_data[ 'menu-item-description' ] = $_menu_item->description;
334
- }
335
-
336
- $menu_items_data[] = $menu_item_data;
337
- }
338
-
339
- $item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
340
- if ( is_wp_error( $item_ids ) )
341
- wp_die( 0 );
342
-
343
- $menu_items = array();
344
-
345
- foreach ( (array) $item_ids as $menu_item_id ) {
346
- $menu_obj = get_post( $menu_item_id );
347
- if ( !empty( $menu_obj->ID ) ) {
348
- $menu_obj = wp_setup_nav_menu_item( $menu_obj );
349
- $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
350
- $menu_items[] = $menu_obj;
351
- }
352
- }
353
-
354
- /** This filter is documented in wp-admin/includes/nav-menu.php */
355
- $walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $_POST[ 'menu' ] );
356
-
357
- if ( !class_exists( $walker_class_name ) )
358
- wp_die( 0 );
359
-
360
- if ( !empty( $menu_items ) ) {
361
- $args = array(
362
- 'after' => '',
363
- 'before' => '',
364
- 'link_after' => '',
365
- 'link_before' => '',
366
- 'walker' => new $walker_class_name,
367
- );
368
- echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
369
- }
370
- wp_die();
371
- }
372
-
373
- }
374
-
375
- $gs_sim = new gsShortCodeInMenu();
376
- $gs_sim_init = $gs_sim->init();
377
- }
378
 
 
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
+ //Silence is golden
public/index.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+
3
+ //Silence is golden
public/js/admin.js ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( 'document' ).ready( function () {
2
+
3
+ jQuery( '#submit-gs-sim' ).on( 'click', function ( e ) {
4
+ // call registerChange like any add
5
+ wpNavMenu.registerChange();
6
+
7
+ // call our custom function
8
+ gsSimAddWidgettoMenu();
9
+ } );
10
+
11
+ /**
12
+ * Add our custom Shortcode object to Menu
13
+ *
14
+ * @returns {Boolean}
15
+ */
16
+ function gsSimAddWidgettoMenu( ) {
17
+
18
+ // get the description
19
+ description = jQuery( '#gs-sim-html' ).val();
20
+
21
+ // initialise object
22
+ menuItems = { };
23
+
24
+ // the usual method for ading menu Item
25
+ processMethod = wpNavMenu.addMenuItemToBottom;
26
+
27
+ var t = jQuery( '.gs-sim-div' );
28
+
29
+ // Show the ajax spinner
30
+ t.find( '.spinner' ).show();
31
+
32
+ // regex to get the index
33
+ re = /menu-item\[([^\]]*)/;
34
+
35
+ m = t.find( '.menu-item-db-id' );
36
+ // match and get the index
37
+ listItemDBIDMatch = re.exec( m.attr( 'name' ) ),
38
+ listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt( listItemDBIDMatch[1], 10 );
39
+
40
+ // assign data
41
+ menuItems[listItemDBID] = t.getItemData( 'add-menu-item', listItemDBID );
42
+ menuItems[listItemDBID]['menu-item-description'] = description;
43
+
44
+ if ( menuItems[listItemDBID]['menu-item-title'] === '' ) {
45
+ menuItems[listItemDBID]['menu-item-title'] = '(Untitled)';
46
+ }
47
+
48
+ // get our custom nonce
49
+ nonce = jQuery( '#gs-sim-description-nonce' ).val();
50
+
51
+ // set up params for our ajax hack
52
+ params = {
53
+ 'action': 'gs_sim_description_hack',
54
+ 'description-nonce': nonce,
55
+ 'menu-item': menuItems[listItemDBID]
56
+ };
57
+
58
+ // call it
59
+ jQuery.post( ajaxurl, params, function ( objectId ) {
60
+
61
+ // returns the incremented object id, add to ui
62
+ jQuery( '#gs-sim-div .menu-item-object-id' ).val( objectId );
63
+
64
+ // now call the ususl addItemToMenu
65
+ wpNavMenu.addItemToMenu( menuItems, processMethod, function () {
66
+ // Deselect the items and hide the ajax spinner
67
+ t.find( '.spinner' ).hide();
68
+ // Set form back to defaults
69
+ jQuery( '#gs-sim-title' ).val( '' ).blur();
70
+ jQuery( '#gs-sim-html' ).val( '' );
71
+
72
+ } );
73
+ } );
74
+ }
75
+ } );
public/js/index.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+
3
+ //Silence is golden
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: gagan0123, saurabhshukla
3
  Tags: Shortcode, Menus, Custom Link
4
  Requires at least: 3.5
5
- Tested up to: 4.3.1
6
- Stable tag: 3.1
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -13,19 +13,16 @@ Allows you to add shortcodes in WordPress Navigation Menus
13
 
14
  Allows you to add shortcodes in WordPress Navigation Menus so that you can generate links dynamically. Also allows you to add full fledged html sections to navigation menus.
15
 
16
- > *Note*
17
- >
18
- > This new version adds a *Shortcode* box on the Nav Menus screen. The earlier functionality using the *Links* box will be deprecated over the next few versions. Please switch to this new box, asap.
19
 
20
  **Usage**
21
 
22
- See the [screenshots](https://wordpress.org/plugins/shortcode-in-menus/).
23
 
24
- Also, see a [great tutorial](https://wordpress.org/support/topic/how-does-it-work-24?replies=22#post-6160111) by Aurovrata Venet
25
 
26
  **Special Thanks To**
27
 
28
- * [Aurovrata Venet](https://wordpress.org/support/profile/aurovrata) for [this great tutorial](https://wordpress.org/support/topic/how-does-it-work-24?replies=22#post-6160111).
29
  * [Lee Willis](https://wordpress.org/support/profile/leewillis77) for finding out and helping in resolving [this bug](https://wordpress.org/support/topic/causes-urls-to-be-amended-in-undesired-ways).
30
 
31
  == Screenshots ==
@@ -78,4 +75,9 @@ Also, see a [great tutorial](https://wordpress.org/support/topic/how-does-it-wor
78
 
79
  = 3.1 =
80
  * Fixed [the bug](https://wordpress.org/support/topic/causes-urls-to-be-amended-in-undesired-ways) with clean_url filters as reported by [Lee Willis](https://wordpress.org/support/profile/leewillis77)
81
- * Made the code translation ready.
 
 
 
 
 
2
  Contributors: gagan0123, saurabhshukla
3
  Tags: Shortcode, Menus, Custom Link
4
  Requires at least: 3.5
5
+ Tested up to: 4.7.5
6
+ Stable tag: 3.2
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
13
 
14
  Allows you to add shortcodes in WordPress Navigation Menus so that you can generate links dynamically. Also allows you to add full fledged html sections to navigation menus.
15
 
 
 
 
16
 
17
  **Usage**
18
 
19
+ See the [screenshots](https://wordpress.org/plugins/shortcode-in-menus/#screenshots).
20
 
21
+ Also, see a [great tutorial](https://wordpress.org/support/topic/how-does-it-work-24/page/2/#post-4987738) by Aurovrata Venet
22
 
23
  **Special Thanks To**
24
 
25
+ * [Aurovrata Venet](https://wordpress.org/support/profile/aurovrata) for [this great tutorial](https://wordpress.org/support/topic/how-does-it-work-24/page/2/#post-4987738).
26
  * [Lee Willis](https://wordpress.org/support/profile/leewillis77) for finding out and helping in resolving [this bug](https://wordpress.org/support/topic/causes-urls-to-be-amended-in-undesired-ways).
27
 
28
  == Screenshots ==
75
 
76
  = 3.1 =
77
  * Fixed [the bug](https://wordpress.org/support/topic/causes-urls-to-be-amended-in-undesired-ways) with clean_url filters as reported by [Lee Willis](https://wordpress.org/support/profile/leewillis77)
78
+ * Made the code translation ready.
79
+
80
+ = 3.2 =
81
+ * Code Refactoring
82
+ * Changed tested upto
83
+ * Corrected links in description
shortcode-in-menus.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Plugin Name: Shortcodes in Menus
5
+ Description: Allows you to add shortcodes in WordPress Navigation Menus
6
+ Plugin URI: http://wordpress.org/plugins/shortcode-in-menus/
7
+ Version: 3.2
8
+ Author: <a href="https://gagan0123.com">Gagan Deep Singh</a> and <a href="http://hookrefineandtinker.com">Saurabh Shukla</a>
9
+ Text Domain: shortcode-in-menus
10
+ */
11
+
12
+ // If this file is called directly, abort.
13
+ if ( !defined( 'ABSPATH' ) )
14
+ exit; // Exit if accessed directly
15
+
16
+ //Lets define some constants
17
+ define( 'GS_SIM_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) );
18
+ define( 'GS_SIM_URL', trailingslashit( plugins_url( '', __FILE__ ) ) );
19
+
20
+ /**
21
+ * The core plugin class
22
+ */
23
+ require_once GS_SIM_PATH . 'includes/class-shortcode-in-menus.php';