Create a Custom Events Admin Page

In this tutorial, we’ll be adding a new admin page which resides under the Events admin menu. This in fact only requires wordpress functions and filters. You could apply this to any wordpress menu, and used on its own, this could work independently of Events Manager.

This tutorial begins our series of tutorials for creating an custom add-on for Events Manager called “Styles”, where we will be able to select from a list of styles during event registration.

Add a submenu item

So first things first. We need to tell wordpress that it needs to add a new sub-menu item to it’s admin navigation.

function my_em_submenu () {
	$plugin_page = add_submenu_page('edit.php?post_type='.EM_POST_TYPE_EVENT, 'Event Styles', 'Styles', 'edit_events', "events-manager-styles", 'my_em_admin_styles_page');
	add_action( 'admin_print_styles-'. $plugin_page, 'em_admin_load_styles' );
	add_action( 'admin_head-'. $plugin_page, 'em_admin_general_style' );
	add_action( 'admin_print_styles-'. $plugin_page, 'em_admin_load_styles' );
}
add_action('admin_menu','my_em_submenu', 20);

The first line adds our new menu item to the Events Manager menu structure using the add_submenu_page function. Note that the last parameter ‘my_em_admin_styles_page’ corresponds to the next function name.

The next three lines are actually not needed in this case, but are left there for example’s sake, as you may want to add these styles and javascript if you need to reuse aspects of Events Manager, such as the date picker, map functionality, etc. In this case it’s not needed and you could just delete or comment them out.

Create the styles page function

This function is called by wordpress if the user is visiting the new admin page we created above. Before we display the page, we need to check if the user has made any style modifications.

function my_em_admin_styles_page() {
	global $wpdb, $EM_Event, $EM_Notices, $my_em_styles;
	$my_em_styles = is_array(get_option('my_em_styles')) ? get_option('my_em_styles'):array() ;
	if( !empty($_REQUEST['action']) ){
		if( $_REQUEST['action'] == "style_save" && wp_verify_nonce($_REQUEST['_wpnonce'], 'style_save') ) {
			//Just add it to the array or replace
			if( !empty($_REQUEST['style_id']) && array_key_exists($_REQUEST['style_id'], $my_em_styles) ){
				//A previous style, so we just update
				$my_em_styles[$_REQUEST['style_id']] = $_REQUEST['style_name'];
				$EM_Notices->add_confirm('Style Updated');
			} else {
				//A new style, so we either add it to the end of the array, or start it off at index 1 if it's the first item to be added.
				if( count($my_em_styles) > 0 ){
					$my_em_styles[] = $_REQUEST['style_name'];
				}else{
					$my_em_styles[1] = $_REQUEST['style_name'];
				}
				$EM_Notices->add_confirm('Style Added');
			}
			update_option('my_em_styles',$my_em_styles);
		} elseif( $_REQUEST['action'] == "style_delete" && wp_verify_nonce($_REQUEST['_wpnonce'], 'style_delete') ){
			//Unset the style from the array and save
			if(is_array($_REQUEST['styles'])){
				foreach($_REQUEST['styles'] as $id){
					unset($my_em_styles[$id]);
				}
				update_option('my_em_styles',$my_em_styles);
				$EM_Notices->add_confirm('Styles Deleted');
			}
		}
	}
	my_em_styles_table_layout();
}

We’re firstly loading the global variable $my_em_styles with an array of the current styles from the wp_options table, and loading an empty array if this record hasn’t been created yet. Following that, we’re going to check if the ‘action’ variable was sent via POST or GET, and if so, we may need to modify the styles list.

if( $_REQUEST['action'] == "style_save" && wp_verify_nonce($_REQUEST['_wpnonce'], 'style_save') ) {
...
}

This section firstly checks that the desired action is saving the event and then verifies that the request originated from the form we will create in the next function. If this all is good, we will add the style to the array of styles. We could save this to a table should we want to, but given we’re only taking a style name and nothing else, this will do.

Note the use of $EM_Notices here, which is a global EM object which we use to add confirmation and error messages and get returned to the user either via AJAX or by displaying on the events page they are viewing.

} elseif( $_REQUEST['action'] == "style_delete" && wp_verify_nonce($_REQUEST['_wpnonce'], 'style_delete') ){
...
}

Like before, this checks that the desired action is to delete and verifies the _wpnonce value. If we’re meant to delete, we remove the style from the styles array and save it back to the database.

Show the styles page layout

Now that we’ve checked and performed actions, we need to show the form with updated values, or simply show them the list of current styles.

function my_em_styles_table_layout() {
	global $EM_Notices, $my_em_styles;
	?>
	<div class='wrap'>
		<div id='icon-edit' class='icon32'>
			<br/>
		</div>
  		<h2>Styles</h2>
		<?php echo $EM_Notices; ?>
		<div id='col-container'>
			<!-- begin col-right -->
			<div id='col-right'>
			 	<div class='col-wrap'>
				 	 <form id='bookings-filter' method='post' action=''>
						<input type='hidden' name='action' value='style_delete'/>
						<input type='hidden' name='_wpnonce' value='<?php echo wp_create_nonce('style_delete'); ?>' />
						<?php if (count($my_em_styles)>0) : ?>
							<table class='widefat'>
								<thead>
									<tr>
										<th class='manage-column column-cb check-column' scope='col'><input type='checkbox' class='select-all' value='1'/></th>
										<th><?php echo __('ID', 'dbem') ?></th>
										<th><?php echo __('Name', 'dbem') ?></th>
									</tr>
								</thead>
								<tfoot>
									<tr>
										<th class='manage-column column-cb check-column' scope='col'><input type='checkbox' class='select-all' value='1'/></th>
										<th><?php echo __('ID', 'dbem') ?></th>
										<th><?php echo __('Name', 'dbem') ?></th>
									</tr>
								</tfoot>
								<tbody>
									<?php foreach ($my_em_styles as $style_id => $style) : ?>
									<tr>
										<td><input type='checkbox' class ='row-selector' value='<?php echo $style_id ?>' name='styles[]'/></td>
										<td><a href='<?php echo get_bloginfo('wpurl') ?>/wp-admin/admin.php?page=events-manager-styles&amp;action=edit&amp;style_id=<?php echo $style_id ?>'><?php echo $style_id; ?></a></td>
										<td><a href='<?php echo get_bloginfo('wpurl') ?>/wp-admin/admin.php?page=events-manager-styles&amp;action=edit&amp;style_id=<?php echo $style_id ?>'><?php echo htmlspecialchars($style, ENT_QUOTES); ?></a></td>
									</tr>
									<?php endforeach; ?>
								</tbody>

							</table>

							<div class='tablenav'>
								<div class='alignleft actions'>
							 	<input class='button-secondary action' type='submit' name='doaction2' value='Delete'/>
								<br class='clear'/>
								</div>
								<br class='clear'/>
							</div>
						<?php else: ?>
							<p>No styles inserted yet!</p>
						<?php endif; ?>
					</form>
				</div>
			</div>
			<!-- end col-right -->

			<!-- begin col-left -->
			<div id='col-left'>
		  		<div class='col-wrap'>
					<div class='form-wrap'>
						<div id='ajax-response'>
					  		<h3><?php echo empty($_REQUEST['style_id']) ? 'Add':'Update'; ?> Style</h3>
							<form name='add' id='add' method='post' action='' class='add:the-list: validate'>
								<input type='hidden' name='action' value='style_save' />
								<input type='hidden' name='_wpnonce' value='<?php echo wp_create_nonce('style_save'); ?>' />
								<div class='form-field form-required'>
									<label for='style-name'>Style Name</label>
									<?php if( !empty($_REQUEST['style_id']) && array_key_exists($_REQUEST['style_id'], $my_em_styles)): ?>
									<input id='style-name' name='style_name' type='text' size='40' value="<?php echo $my_em_styles[$_REQUEST['style_id']]; ?>" />
									<input id='style-id' name='style_id' type='hidden' value="<?php echo $_REQUEST['style_id']; ?>" />
									<?php else: ?>
									<input id='style-name' name='style_name' type='text' size='40' />
									<?php endif; ?>
								</div>
								<p class='submit'>
									<?php if( !empty($_REQUEST['style_id']) ): ?>
									<input type='submit' class='button' name='submit' value='Update Style' />
									or <a href="admin.php?page=events-manager-styles">Add New</a>
									<?php else: ?>
									<input type='submit' class='button' name='submit' value='Add Style' />
									<?php endif; ?>
								</p>
							</form>
					  	</div>
					</div>
				</div>
			</div>
			<!-- end col-left -->
		</div>
  	</div>
  	<?php
}

Since I’m not trying to write a wordpress tutorial here, I won’t delve into the intricacies of this, suffice to say that it generates an HTML form that users can view the table of styles and also input a style name via a single field form. However, it’s worth pointing out the $EM_Notices function. You’ll notice we made this a global variable at the top of the last two functions, this is because in the second function we’ll display any errors or confirmation messages generate by EM. All you have to do is echo the $EM_Notices variable, the class will do the rest!

In our next tutorial, we will create a custom meta box for the events registration page, so that we can add and edit information.