New Release: phpSmug 4.0.0

Wow!!! Look at that, a new release of phpSmug!!! :grin: phpSmug 4.0.0 is finally here.

Yes, I know, it’s been a long time coming, but there hasn’t been a need to release another version since I released phpSmug 3.5 back in March 2013, until SmugMug released their newest API, and even then, it was in a long beta. The deprecation of the 1.3.0 API was the kick in the pants I needed to finish off phpSmug 4.0.0.

So what’s new in phpSmug 4.0.0? I’m glad you asked.

For a start, it’s a complete rewrite. Rather than maintaining my own code to perform the HTTP requests, I’ve switched to using Guzzle. This allows me to concentrate on phpSmug and let someone else concentrate on the finer details of actually talking HTTP. It does however mean phpSmug 4.0.0 and later is not a drop in replacement for phpSmug 3.x.

This has a big advantage in now phpSmug can take advantage of Guzzle’s functionality without too much effort. Whilst phpSmug still doesn’t have support for asynchronous requests, it shouldn’t be too hard to implement it in future as Guzzle already has this functionality. This use of Guzzle also means we can extend phpSmug with relative ease.

phpSmug is now installed using the industry standard method of using Composer. This makes it easier to integrate phpSmug with your projects and pull in all of the dependencies.

And of course, phpSmug is now compatible with SmugMug’s vastly superior v2 API. This has got to be one of the best APIs I’ve worked with. This does unfortunately mean phpSmug 4.0.0 and later is not backwardly compatible with the now deprecated 1.x.x API.

Some other changes include the publication of the test suite. I used to have a test suite before, but due to the embedding of credentials, it was kept private. The switch to Guzzle means I can use Mock objects to test phpSmug without revealing any credentials.

A few lesser changes and improvements:

  • phpSmug now uses semantic versioning.
  • phpSmug is now licensed under the MIT license.
  • Unit tests are run with every push to the GitHub repository.
  • PSR-1, PSR-2, and PSR-4 coding standards are implemented and enforced by unit testing.

Other than that, phpSmug is pretty much the same as it was before.

So what’s on the cards for phpSmug in future?

Well, I’d like to bring back caching, and in a significantly more intelligent method than before. I’d also like to introduce asynchronous uploads for a start, and then maybe extend that to all requests. If you’d like to help out, please feel free to do so. Check the About page or the for more details on how you can help.

If you have any questions or hit any problems, please open an issue and I’ll do my best to help you out as soon as I can.

So what are you waiting for? Go download phpSmug 4.0.0 NOW!!

#phpSmug On Twitter

Need a quick bit of help, have a quick question, want to show off your app using phpSmug or just want to say thanks for phpSmug? Please feel free to do so on Twitter using the #phpSmug hash tag. There’s a button on the sidebar too to help you :-)

Provided I’m not on holiday, I’ll normally respond, if necessary within a couple of hours of your tweet - normally minutes if during UK business hours :-)

phpSmug Now on GitHub

Well, finally the day has come for me to put the phpSmug source code onto a public repository.

I’ve just spent the morning converting my internal Mercurial repo to a Git repo and uploading to GitHub. I have also manually transferred all the bugs logged to issues on GitHub.

So with phpSmug out on GitHub, please feel free to log issues on GitHub or fork the code and submit your changes via pull requests.

New Release: phpSmug 3.4

Only a single small change in phpSmug 3.4: phpSmug was neglecting to set the appropriate “hidden” upload header when uploading photos that should be marked as hidden. phpSmug 3.4 now resolves this and “hidden” uploads should now show up as hidden when they arrive on SmugMug.

This resolves ticket #12.

phpSmug 3.4 is now available from the download page.

New Release: phpSmug 3.3

Well, hot on the heels of phpSmug 3.2 comes phpSmug 3.3.

For a long time now, I’ve been working around what I thought was an undocumented change in the way the API was handling the boolean literal FALSE and empty strings. My workaround seemed to work well for boolean literals, but fell apart when an empty string value was passed to the API, like when unsetting an album’s password, as Anthony Humes discovered and from which I created ticket #11.

Well, after a bit of digging I discovered the problem was NOT with the API, but rather the way PHP’s implode() and http_build_query() functions handle associative arrays with empty values. implode() seems to completely ignore the empty value when imploding and http_build_query() converts the empty value to a 0. Neither of which were desired behaviours and both of which I didn’t notice until now.

phpSmug was using both of these methods in different places to effectively come to the same result - concat the keys and values into a single string for the POST data and for calculating the signature.

I have now fixed this by implemented a different method of reliably concatting the keys and values for submission to the API endpoint and for the signature calculation. The result of this is now 0, an empty string and the boolean literal FALSE all equate to FALSE and works with the API. Empty string values are now also correctly handled so doing things like unsetting passwords will now work too.

phpSmug 3.3 is now available from the download page.

New Release: phpSmug 3.2

Ladies and gentlemen, phpSmug 3.2 is now available for you.

Once again, this is a minor release and features a few “behind the scenes” changes and fixes which do not change the functionality. phpSmug should now work properly with the 1.3.0 API endpoint. I’ve also added the ability to force all API communication, except for uploads, to occur over HTTPS if you use OAuth for authentication. SmugMug are encouraging people away from using basic login authentication in favour of OAuth (the 1.3.0 endpoint has no support for basic authentication) so accordingly, I have not implemented the “secure only” functionality for basic authentication. I may add it at a later date if there is the demand for it.

The changelog entry for phpSmug 3.2 is…

  • Improved support for the 1.3.0 API endpoint (#10)
  • Implemented the ability to force all API communication to occur securely over HTTPS. OAuth Only. (#9)
  • phpSmug now uses the documented API endpoints (#8)
  • Updated OAuth example to use new Album URL and to remove its use of the deprecated session_unregister() PHP function. phpSmug 3.2 is now available from the download page.

New Release: phpSmug 3.1

Time for another update of phpSmug. I’ve just made phpSmug 3.1 available.

This is only a minor update which features a few “behind the scenes” changes and fixes which do not change the functionality. The only thing that may appear to change functionality is the default API endpoint is now 1.2.2 instead of 1.2.0. All earlier endpoints are still available, but technically deprecated by SmugMug.

For the curious, the exact changes from the change log are:

  • phpSmug now defaults to using the 1.2.2 API endpoint. All earlier endpoints are still available, but technically deprecated by SmugMug.
  • Removed erroneous re-instantiation of processor when setting adapter.
  • Corrected check for safe_dir OR open_basedir so fails over to socket connection correctly
  • Improved connection settings

phpSmug 3.1 is now available from the download page.

SmugMug Needs Your Help

I’ve been slacking a bit on the SmugMug DGrin API forum, but I popped by today and noticed a call for help from Don MacAskill …

We’re seriously revamping the way we handle the API, support, announcements, and discussions around it. It’s become a very important part of what SmugMug does, and our developers (that’s you!) are super important.

As part of that, we’re trying to set up a StackExchange site and could use your help, especially if you use StackOverflow, but any and all help helps. :)

Please read my blog post about StackExchange here:

And thanks in advance for your help! More to come about the way we’re going to handle announcements, improvements, end-of-life, etc, as we continue to think about it internally.

Essentially, SmugMug want to start using StackExchange for hosting Q&A and other useful information for users and devlopers, but in order to even get considered for a beta, they need 100% commitment from people to say they will use the SmugMug Q&A on StackExchange.

If you’ve ever used StackOverflow or other stack sites, you’ll know what a great resource this is and how useful this can be for everyone, so please head on over to StackExchange, hit ‘Commit’, fill in your details (your SmugMug URL works as an OpenID!), and then click the link in the email they’ll send you.

The more commits they get, the quicker they’ll get to start the beta phase.

New Release: phpSmug 3.0

After a long delay, with a known bug (Issue #7) floating around in phpSmug 2.2, I’ve finally pushed phpSmug 3.0 out the door.

The primary delay has been due to a major rewrite of a large portion of the backend code. I’ve removed the dependency on PEAR for the out-the-box phpSmug. I’ve removed this dependency because the code I was using was outdated and the newer versions of the various modules were quite unreliable. I also wasn’t too happy with these modules still offering PHP 4 support when PHP 4 has been EOL’d for so long either.

PEAR isn’t completely written off. phpSmug still uses PEAR’s MDB2 modules for those who wish to use database caching. As this is an optional dependency - filesystem caching doesn’t need PEAR - phpSmug no longer ships with any PEAR modules. If you want this functionality, you need to install the modules yourself. The documentation details this too.

Along with this major update, a few other things have changed:

  • The removal of the dependency on PEAR now gives developers the opportunity to select a preferred transport mechanism, or adapter: Curl or sockets. phpSmug defaults to using Curl, but will gracefully fallback to sockets in the event Curl isn’t available.
  • More specific exceptions are thrown so developers can easily identify which part of the code is throwing the exception. The exceptions now thrown are PhpSmugException, HttpRequestException and CurlRequestProcessorException or SocketRequestProcessorException.
  • phpSmug is now PHP 5 E_STRICT compliant, which finally resolves Issue #2
  • I’ve fixed the problem with the OAuth token not being set correctly in phpSmug 2.2 (Issue #7)
  • phpSmug is now licensed under the GPLv3 instead of the LGPL.
  • The underlying phpSmug code is now better formatted, documented and laid out making it easier to follow. My backend code generation and testing is also more streamlined so it’s easier for me to update and test changes, which should mean it won’t take so long to release fixes.

And last but not least, I’ve moved to a new host and given the site a slightly different look. It’s not a major change, but it’s there.

phpSmug 3.0 is now available on the download page.

If you spot any issues, let me know. Oh and don’t forget to drop me a line if you have a product that uses phpSmug that could do with a bit of free advertising.

New Release: phpSmug 2.2

It’s been a while since I last released an update to phpSmug, but rest assured I’ve not forgotten phpSmug and have actually been working on some of the behind-the-scenes stuff. Most of the work I’ve been doing has been on building a test suite for my own purposes so I can thoroughly test phpSmug with ease.

This is list of the changes you as a developer/user may notice (taken from the README.txt):

  • https is forced for all calls that use OAuth with the PLAINTEXT signature method. WARNING: Uploads are however rejected by the API if you use PLAINTEXT (which is NOT the default).
  • Failed upload responses and smugmug.auth.* method responses are no longer cached.
  • Upload filenames are now encoded to ensure spaces and non-ascii characters are correctly handled.
  • images_upload() now honours any earlier setProxy() calls so uploads can occur through that proxy.
  • clearCache() now takes a boolean argument to state whether you want the cache location to be removed when the cache is cleared. Default is FALSE, ie the cache location will NOT be removed
  • Added methods to handle calling of the various login.* methods offered by the API when using these instead of the single login() method offered by phpSmug. (Issue #6)
  • For my own benefit, I’ve now implemented a full PHPUnit test suite that checks all functionality of phpSmug.

phpSmug 2.2 is now available on the download page.

Given the relative silence from users, I’d say not many people have encountered these or they’re easily found a workaround.

If you spot any issues, let me know. Oh and don’t forget to drop me a line if you have a product that uses phpSmug that could do with a bit of free advertising.

New Release: phpSmug 2.1

Time for a relatively major update that primarily fixes uploading and caching.

SmugMug have enforced the use of for all uploads. All earlier releases of phpSmug uploaded to, and whilst this worked, apparently SmugMug were having problems with people using this endpoint for uploads, so they’ve now forced people to use the correct url :-) (Issue #5).

Other changes in this release include fixing a problem spotted with caching - data was being re-cached everytime a method call was called, even if the data was read from the cache in the first place. (Issue #4)

phpSmug now also stores SmugMug’s mode in the $obj->mode object variable for easy checking of SmugMug’s status. This variable is only populated if SmugMug is in read-only mode.

I also fixed the “login with hash” example in the README file.

phpSmug 2.1 is now available on the download page.

New Release: phpSmug 2.0.2

Just a small minor update to phpSmug that resolves the over zealous clearCache() (Issue #3) and some code tidying to get phpSmug a bit closer to being E_STRICT “compliant” (Ticket #2). Sadly we’re still tied by PEAR for full compliance, bit for the moment all the code I have control over works with E_STRICT.

As usual, it’s available for download from the download page.

clearCache() is Over Zealous

I’ve just found another bug (#3 logged) in phpSmug that you should be aware of. The clearCache() function is over zealous when using the filesystem as the cache location. The function deletes ALL files in the specified directory, not just it’s own.

This isn’t a problem if you’ve specified a unique directory for caching, but if you’re using a shared caching directory, like you may do if including phpSmug in an application, then all the cache files are removed.

In order to rectify this, I’m going to have to change the caching filename or directory scheme to uniquely identify the phpSmug specific cache files so phpSmug can quickly and easily identify them when clearing the cache.

I’m considering changing phpSmug such that it creates it’s own dedicated directory in the location specified in the enableCache() method call. The DB caching method creates it’s own table, so it only makes sense that the FS method creates it’s own directory.

This bug does not affect database caching as phpSmug creates it’s own table for the cache entries.

I’ll fix this in the next release.

phpSmug and PEAR Module Instantiation with PHP5 and E_STRICT

I’m in the process of creating a project using my phpSmug class and I’ve discovered I’m not quite 100% PHP5 E_STRICT compliant in two locations in the way I instantiate new PEAR objects:

105    $this->req = new HTTP_Request();
472    $upload_req = new HTTP_Request();

(105 and 472 are the line numbers.)

This instantiation by reference is going to result in errors similar to:

PHP Fatal error: Class '<CLASSNAME>' not found in /path/to/file.php on line ###

… where <CLASSNAME> will possibly be a class that isn’t even supplied as part of phpSmug and line ### will be the line in which the class has been instantiated using the =& new code.

There’s no need to instantiate by reference anymore in PHP5. PHP5 will actually throw the above error as it’s ambiguous. Now this is easy enough for me to fix in the files I ship (which I’ll do in the next release), however it’s more of a challenge to correct the files I have no control over, like PEAR modules.

Unfortunately, PEAR has (had? - the source seems quite old) a backward compatibility requirement which unfortunately includes the requirement of instantiating objects by reference to keep PHP4 happy. PHP4 is now EOL, so maybe that requirement has been dropped.

I’m going to need to do some research to see how I can resolve this. This may mean forcing the use of the classes supplied with phpSmug ahead of those supplied by your ISP/system. I provide these only for convenience at the moment, but I may need to change that to “necessity”.

If you encounter a similar situation, you can resolve the issue by replacing all instances of =& new with = new when objects are being instantiated.

Update: It looks like this is only when E_STRICT error reporting is set. Lowering the level allows things to work as expected. Issue #2 logged to get phpSmug E_STRICT compliant.

New Release: phpSmug 2.0.1

Thanks to MVA for pointing out a rather silly mistake I made in phpSmug 2.0 - I wasn’t passing the error code correctly to Exception() on line 350 (Issue #1).

As this involves something quite crucial, I’ve released a minor update to rectify this. This is now available for download now.

New Release: phpSmug 2.0

Finally, after 7 months of slow, but steady development, I’m happy to announce phpSmug 2.0 is now available for download.

It’s been a long time coming as there has only been one bug reported in the last release, and it wasn’t a major issue, and I’ve been working on consolidating the code to make it more uniform and a lot easier to manage and maintain.

What’s New?

First things first, I have to issue a warning:


phpSmug 2.0 is NOT a drop in replacement for phpSmug 1.0.x of 1.1.x.

Please ensure you read this post, which is also documented in the README and the documentation, for details on how phpSmug 2.x now functions.

Right, now we’ve got that out of the way, lets get to the nitty gritty.

For those who’ve used phpSmug before, things have changed with phpSmug 2.0 and hopefully it’s for the good and won’t be too much trouble to adapt your applications for.

If you’ve not used phpSmug before, you can skip the rest of this post as it won’t mean much to you.

  • Method Arguments The general functionality is the same, however the method of passing arguments to methods has changed. Now when you pass arguments to a method, you need to pass them either as a series of strings, for example:

    $f->images_getInfo("ImageID=<value>", "ImageKey=<value>");

    … or as an array …

    $f->images_getInfo(array("ImageID" => "<value>", "ImageKey" => "<value>"));

    This is a deliberate design decision to keep things consistent and is actually due to work I’ve done to ease the development and maintenance of phpSmug.

    You’ll see phpSmug 2.0 is considerably smaller than previous versions. This is because phpSmug now uses PHP 5’s __call() method to dynamically create the API calls for methods that are not explicitly declared.

    As a result of this, phpSmug 2.0 and later will definitely NOT work with PHP4. It also has the added bonus in that you no longer need to have empty arguments in your method calls: you only need to pass what’s required or what you need.

  • SmugMug API Endpoint Compatibility phpSmug 2.0 defaults to using the only stable endpoint provided by SmugMug: the 1.2.0 endpoint. However, it is fully functional with the later endpoint revisions, unless otherwise documented on the Issues page. To use a later version of the endpoint, just set the version when instantiating the instance using APIver.

  • All smugmug.login.* Methods Handled by a Single login() Method To simplfy things even further, I’ve consolidated all the smugmug.login.* API methods into a single login() method. phpSmug will determine which API method you wish to use from the arguments passed when calling the method. If not arguments are passed, phpSmug will login anonymously.

  • phpSmug now throws exceptions on error In order to take full advantage of PHP5 functionality and make phpSmug behave more like a proper PHP class, I’ve removed the “die_on_error” functionality and instead turned to using exceptions. It’s up to you as the application developer to catch the exceptions and turn it into something useful for your users. All the examples supplied with phpSmug now catch the exceptions. The only exception to this is caching. If there is a problem creating the cache, phpSmug will just error and continue without using any caching. I didn’t think it worth stopping the world due to a caching issue.

So, go on, get downloading and if you encounter any problems, please leave a comment on this post.

Welcome to phpSmug's New Home

Ladies and gentlemen, welcome to phpSmug’s new home -

As phpSmug has grown to take up a fair amount of my time and it’s starting to be used by more and more projects, I thought it’s about time it got it’s own home, instead of hiding in a corner of my tech site. And this is it.

If you’re using phpSmug in your application, and want a bit of link love, let me know and I’ll add a link back to your application site (and hopefully you’ll reciprocate ;-) ). I’ve not setup a dedicated section for this yet, but as I’m thinking about it and hope to setup a dedicated section in, probably in the sidebar, once I’ve got a nice list of applications going.

It’s early days for this site so it may be a little rusty around the edges, but if you spot any problems, leave a comment on this post.