WordPress and the Admin Bar

So WordPress 3.1 introduced the new admin bar. Essentially its another way to navigate around your WordPress Blog’s inner workings, the bar itself can be enabled and disabled both inside and outside the admin system, for I like to have it enabled on both the admin and non admin sides of WordPress.

The WordPress.com Stats Plugin makes quite good use, on the non admin side, by showing a graph of site visits over the last 48hours:

This led me to think about how to put my own links on, so I turned to adding the navigation from YourMembers to the admin bar (but in this case on Both Sides, admin and non admin).

Won’t show you a admin side one as it looks exactly the same 😛

Actually writing the code to make the YourMembers navigation be added to the nav bar, is actually relatively simple, since the admin bar itself has been written rather nicely in its own class.

Opening up the admin-bar.php file in wp-includes is a bit messy, but looking at the first function (_wp_admin_bar_init) shows the class function add_menus() and further down add_menu, so off I went to find them…. A quick grep later finds that is class-wp-admin-bar.php and from there just a matter of reading what add_menu wants….

<?php

	function add_menu( $args = array() ) {
		$defaults = array(
			'title' => false,
			'href' => false,
			'parent' => false, // false for a root menu, pass the ID value for a submenu of that menu.
			'id' => false, // defaults to a sanitized title value.
			'meta' => false // array of any of the following options: array( 'html' => '', 'class' => '', 'onclick' => '', target => '', title => '' );
		);

I went thru and checked to see where the other “normal admin” links were being added, the function add_menus in the same class file shows that. The key thing to be aware of is the use of priority on those do_actions (line 182 thru 194) in order to order the links, so needing/wanting the YourMembers links to be at the end I went for a sensible priority of 90 since the last normal admin was set to 80.

Then it was just a matter of setting up my own add_action on the same hook (‘admin_bar_menu’) and then globalising the pre existing class method and adding my menus to it.

Since it is a drop down menu, needed to add the top menu as a parent and then adding the child nodes.

Its quite a clever class since the class function of add_menu can handle both parents and childs at the same time with little fuss, as long as you pass it the right ID variables.

Heres a copy of my function:

<?php

function ym_admin_bar() {
	global $wp_admin_bar;

	if (ym_admin_user_has_access(TRUE)) {
		$wp_admin_bar->add_menu(
			array(
				'id'		=> 'yourmembers_adb',
				'title'		=> 'Your Members',
				'href'		=> YM_ADMIN_INDEX_URL
			)
		);
		global $ym_nav;
		foreach ($ym_nav as $page => $subpages) {
			if (is_array($subpages)) {
				$first = array_shift($subpages);
			} else {
				$first = '';
			}
			$id = 'ym_adb_' . strtolower($first);
			$url = strtolower($first);
			if (substr($first, 0, 5) == 'other') {
				$url = 'ym-other&action=' . substr($first, 6);
			}
			$wp_admin_bar->add_menu(
				array(
					'parent'	=> 'yourmembers_adb',
					'id'		=> $id,
					'title'		=> $page,
					'href'		=> YM_ADMIN_INDEX_URL . '&ym_page=' . $url
				)
			);
		}
	}
	return;
}
add_action('admin_bar_menu', 'ym_admin_bar', 90);
?>

There are a couple of funky bits in there due to the method we currently generate the nav items.
The essential bit to consider is the array passed to $wp_admin_bar->add_menu at the start (the parent element note, no parent key) and the $wp_admin_bar->add_menu at the end, specifying a child element.

The function ym_admin_user_has_access just checks to see if the user is of the correct level or not.

You might want to throw in a switch on is_admin() to return different navigational items depending on if you are in the admin or not.

I’m sure there is a lot more you can do with the class function but when I installed WordPress 3.1 and saw the admin bar and WordPress.com Site stats this was the first thing I thought of and implemented, tho why its taken me this long to blog about it I don’t know…..

Travels of a Commercial WordPress Plugin Developer 1

My job at the moment is updating and coding YourMembers, which is a commercial plugin for WordPress.

Recently I’ve been working on a method to Auto Upgrade the plugin, since commercial plugins cannot go on Extend, and there is no commercial equivalent. Extend being the WordPress plugin repository.

Commercial plugins get no nice little “Plugin needs updating Circle” on the plugins tab, or a nice little message on the plugins page, let alone access to the auto updater!

Which leaves us (commercial plugin devs) to write our own version checkers and hook in accordingly.

So now I have a nice little PHP class which will detect whether it can fwrite/rename and if not if it can FTP instead, much the same as the WordPress updater does.

Now this is all well and good, but I needed a method to download and unzip the new plugin file. Grabbing the file is easy, either file_get_contents (heaven forbid), or curl (yay for curl), and write the file (being a zip) to the web servers temporary directory and process from there.

Now the problem here is how to unzip. A Brief look at how WordPress does it seems to show it has three different methods of unzipping. So dump that.

Didn’t feel the need to use PHP’s ZipArchive class, since I don’t need to edit the zip, just extract its contents.

Off to php.net I go and I find some nice handy functions, and quite surprised to find that the zip_read function can handily recurs into directories within the zip file to return their paths/names. Mildly annoying at the time as I had gone and written a recur loop to go inside directories…. and got thrown a error, nice headdesk moment!

So basically the Zip functions, the basic ones of PHP, are actually quite nice, handy and useful!

Heres my code snippet:

<?php
class someclass() {
	private function unpack() {
		$from = $this->tmp_write;
		$to = $this->tmp_out;
		@mkdir($to);
		
		$zip = zip_open($from);
		if (is_resource($zip)) {
			$this->readzip($zip);
			zip_close($zip);
		} else {
			// failed to open
			$this->error = 1;
		}
	}
	
	private function readzip($zip) {
		$from = $this->tmp_write;
		$to = $this->tmp_out;
		
		echo '</pre><textarea style="width: 100%; height: 100px;">';
		
		while (FALSE !== ($file = zip_read($zip))) {
			$name = zip_entry_name($file);
			echo $name . "\n";
			if (!strpos($name, '.')) {
				// is dir
				@mkdir($to . '/' . $name);
			} else {
				// it recurs into directorys on its own!
				$item = zip_entry_open($zip, $file);
				$size = zip_entry_filesize($file);
				
				$read = zip_entry_read($file, $size);
				$fp = fopen($to . '/' . $name, 'w');
				fwrite($fp, $read);
				fclose($fp);
			}
		}
		
		echo '</textarea><pre>';
	}
}
?>

I just installed this code snippet plugin, which I might need to change its background colours…..

Any suggestions for code snippet plugins greatly appreciated!

SOLD and All Change!

So I left my job at Vanguard SEO as the start of this year for two reasons, one got a better job offer, and two the company went bankrupt. Not very lolworthy.


Anywho, I have been contracting for NewMedias, as a PHP Developer, since September Freelance style, and more 9-5 contracting during January and then NewMedias overlord Apeei, sold the company for mere bananas to CodingFutures, and then they offered me a job, so there I am now as a PHP Developer! And now we are nearly at the end of week two of my new job.


This week we had some nice photos done heres me and the rest of the team!

So these days I find myself working on YourMembers a WordPress plugin for Subscription and post control among other things. As well as the plugins for it. I built from the ground up YSS – Your Secure Stream, which can create links with expiry for Amazon S3 Hosted content, so people who use WordPres can provide Audio and Video, whilst protecting that content too! It plugs in to FlowPlayer and Longtails JWPlayer, some of the more commonly used players.

This week I’ve been working on the Mail/AutoResponder Plugin. Its been going well and should hopefully be finished soon 😀

Thru my work I’ve been getting to know WordPress more and the most useful link I’ve found today, is how to integrate TinyMCE, the Visual/HTML editor for WordPress, into your own Plugins. I’ve expanded on some of the code from the second link for the Visual/HTML editor switch, in order to handle multiple instances of TinyMCE on a page, as well as the core code. Mainly since the page I am using TinyMCE on, is generated thru a Form Generation Class I didn’t write and should at some point redo, its a nice class but has some interesting caveats and limitations. Let along the fact I havn’t managed to get WordPress using my usual jQuery DateTime Picker I like, since WordPress uses a old version of jQuery and jQuery UI, and if you load latest, its gonna break someone else’s plugin, installed on a client site, and to top it all WordPress loads the jQueryUI CSS for the latest version for Google CDN.

On a side note using Google CDN’s jQuery is very good and better, check this link for reasoning, and this one for implementation (in general not just WordPress).

I think the key point for using Google Code hosted jQuery, is that pages will load quicker, since more domains mean more open HTTP connections, as browsers limit the connections open to a single domain at once. About 6 according to the reasoning link, so more domains means more open HTTP connections which means pages can load more quickly. Let alone the fact that if everyone loads from Google Code, then its cached on the users machine, which means from site a to site b, on site b, user doesn’t have to load jQuery as its already in the Cache. Thus making page loads quicker!

Still need to find a link explaining how to use the WordPress collapse a box, that all the WP-Admin grey bars and boxes do. I have built my own function in jQuery to do it, but it doesn’t (yet) have the cookie elements that WordPress’es own has to remember which are open/closed when the page reloads. Since seem there is no easy documented way on how to use the in built functionality.

Either that or I’ve missed it.

Also lately been working with the MailChimp API, had to laugh at the URL: http://apidocs.mailchimp.com/rtfm/.

On that bomb shell, catch you later, I’ve felt like I’ve rambled on a lot when this post was looking quite short…. Must blog more. Keep an eye on my Tumblr for more real time snippets of stuff, I’m assuming you already follow me on Twitter…..

Some Random Useful Things

Some random useful things:

Twitter, is scrapping Basic Auth! Which means no more simple curl calls, its on to OAuth.

Check out http://dev.twitter.com/pages/basic_to_oauth for how to update your Apps/Usage, and http://countdowntooauth.com/ for a handy countdown.

In other twitter news, I use Notifo to forward my twitter replies to my iPhone, which uses Push.ly to grab the stream. Twitter has currently borked @Replies both in apps and on the website, however Notifo announced they have updated their website with a new design, (hurrah), and a desktop client (further hurrah).
So with my mac and growl I now get Growl @ Responses….. SUCCESS!

Thats enough twitter! I was linked in a random IRC channel to http://jsfiddle.net/, which is a sort of real time code and run/test interface for several different javascript libs, including MooTools, and jQuery. Its currently in Alpha and under “heavy development”, so far I have found it quite useful, since it saves a lot of time in prototyping something. Looking forward to when they add user accounts, will be easier to track my own fiddles, heres the 5th version of me fiddling with jQuery UI tabs yes it has basic version control!

Facebook next, came across this today: http://developers.facebook.com/roadmap pretty much nails the coffin shut on FBML and suggests that we will all be using iFrames instead….

Not sure if this is a good thing or a bad thing, since iFrames are not always the most secure of things, but will make sending more upto date stuff to a Facebook page easier. And no longer stuck with Facebook caching, which in itself is a useful thing….

Also they are moving to a larger oauth setting with the use of oauth version 2! And scrapping their Rest API.

So there is a lot of change going on within two of the larger things I have been involved with (in terms of building things for clients), so in this vein when is the Last.FM api moving to oAuth too, tho it does use a token based Auth now?!

I’m gonna need to do a lot of recoding/refactoring for things that use FBML and basic Auth….

Is oAuth the future for all API’s? What do you think?

Edit:

O and I am going to invest in one of these!

Summer

So that middle part of Summer has been a bit sucky. So we shall skip all that, don’t really want to go into it….

Now things are better!

I lost my mac for a week and a half, hard drive failed, followed by back for two hours, followed by hard drive fail.
In the end Clockwork (Leeds Apple Care), replaced the drive and the drive’s cable, and shes all good now!

I’m off to Moor Fest next week, I’m doing the lighting for the Green Room, with Chamsys and whatever fixtures I get given, learnt some useful things from their Chamsys Guide for that matter, (and I fixed up the tab box on the home page for them!) Nice bit of jQuery!

Made a shoutbox for Halo3Wheelmen its hosted on 360gaming.net so had to do a lot of fudging and built a mini phpBB api to get user/ban data out of the forum, its all built in jQuery and PHP, jQuery makes ajax stuff, and append/prepend so much easier than pure javascript.


Job wise I am still waiting to hear back from Firebox.com, but it looks like I shall be staying in Leeds for another year at least, being a Venue Tech, which should, with the new boss, hopefully lead to more external work, but I shall still be working as a freelance web developer. Tho there have been some interesting local jobs come up on the GeekUp jobs Board. (I need to start going to GeekUp again….)

In that vein I currently have a bit of work on building a Asset/Event Manager for LUU Events, details on that to follow, but as a project it keeps me out of trouble, since Google fell thru.

Hopefully I should be getting back into modding phpBB which is even easier now since they now use GitHub to host their repository, so I’m gonna have to get to grips with forks, and loading parent data into the child repo…. (If that makes sense).

So essentially things are busy, not perfect but good. Could be better could be worse…

Hopefully at some point I will get around to doing a Carlyon CMS release candidate, tho I am thinking I need to rip out my CSS boilerplate and thus the relevant core html template files, we shall see.

In other news, I now have completely new graphics for 360gaming [dot] net, I was approached and offered the services of O Sheep Dip, and now I have graphics! Woot!
360gaming.net now has a HogBall league tracker on top of the 1v1 challenger system, tho no one has tested it yet, and I only have the one team, people don’t seem interested…

Tho there is a BTBhub on the way, it was suggested to me that building a BTB league is the way to go, and now I have the core Bungie Code checker, and with the advent of Reach, its data API (POTATO!) and of course, its massive ForgeWorld, the future is bright for Halo and 360gaming.net, now all I need is to find more games with similar developer offerings, and getting myself access to the true Xbox API……

So that summarizes the later part of summer… O and Katie is now home.

Also checkout my tumbleblog

Catch you after Moor Fest, (which will be my first ever festival, I’ve never been to one, and now the first one I am going to is also going to be my first external lighting job….)

Off to watch Sherlock on BBC1

And Happy Birthday to Kayleigh (The GirlFriend) 🙂