Overview

phpSmug is a PHP wrapper class for the SmugMug API. The intention of this class is to allow PHP application developers to quickly and easily interact with the SmugMug API in their applications, without having to worry about the finer details of the API.

Not already a SmugMug user? Here, have a $5 discount off your first year on me by registering using this code:

2ZxFXMC19qOxU

The development of phpSmug takes place in my free time. If you find phpSmug useful and found it has saved you a lot of time, I’d really appreciate it if you bought me a coffee or two.

Buy me a Coffee


Requirements

Installation

The recommended method of installing phpSmug is using Composer. If you have Composer installed, you can install phpSmug and all its dependencies from within your project directory:

$ composer require lildude/phpsmug

Alternatively, you can add the following to your project’s composer.json:

{
    "require": {
        "lildude/phpsmug": "^4.0"
    }
}

.. and then run composer update from within your project directory.

If you don’t have Composer installed, you can download it using:

$ curl -s http://getcomposer.org/installer | php

Basic Usage

phpSmug follows the PSR-1, PSR-2 and PSR-4 conventions, which means you can easily use Composer’s autoloading to integrate phpSmug into your projects.

<?php
// This file is generated by Composer
require_once 'vendor/autoload.php';

// Optional, but definitely nice to have, options
$options = [
    'AppName' => 'My Cool App/1.0 (http://app.com)',
];
$client = new phpSmug\Client('[YOUR_API_KEY]', $options));
$repositories = $client->get('user/[your_username]!albums');

For convenience, phpSmug only returns the json_decoded Response part of the response from SmugMug. If you wish to access the full json_decoded response, you can do so with $client->getResponse();.

From the $client object, you can access to all the SmugMug 2.0 API methods.

More In-depth Usage Details

Instantiating the Client

The phpSmug\Client() constructor takes two arguments:

  • Your API key as a string - Required.

    This is required for all interaction with the SmugMug API. Apply for an API Key here.

  • An array of options - Optional.

The options you pass here become the default options applied to all requests by default, unless explicitly overwritten elsewhere and can be made up of any combination of the following options:

  • AppName - The name, version and URL of the application you have built using the phpSmug. There is no required format, but something like My Cool App/1.0 (http://my.url.com) would be very useful.

    Whilst this isn’t obligatory, it is recommended as it helps SmugMug identify the application that is calling the API in the event one of your users reporting a problem on the SmugMug forums.

  • OAuthSecret - This is the secret assigned to your API key and is displayed in the Settings tab of the SmugMug Control Panel. If no secret is displayed, select “change” next to the API key your application will use and click “save”. A secret will be generated for you.

    An OAuthSecret is required for all access to the SmugMug API that requires authentication.

  • _verbosity - Determine how much information you’d like to get from SmugMug by increasing or decreasing the verbosity. Defaults to 2. See Optimizing response sizes for more information.

    This option can be overruled on a per-request basis too.

  • _shorturis - If this parameter is set, the URI section of the response object will be trimmed down so that each entry is just a key-value pair of name to URI. This removes all metadata about the URI from the response. See Optimizing response sizes for more information.

    This option can be overruled on a per-request basis too.

  • api_version - The API version you wish to use. This defaults to v2 as this is the only version of the API this version of phpSmug is compatible with. This is really only for “future proofing”.

Additionally, you can pass any Guzzle request option though debug and proxy are probably the only options you may need to set.

Interacting with the SmugMug API

Once you’ve instantiated an instance of the phpSmug\Client, you can use the simplified Guzzle HTTP method calls to interact with the API.

Note: phpSmug does not currently support asynchronous requests, though now we rely on Guzzle, this shouldn’t be too hard to implement in future.

GETting Information.

To get information about a user, gallery, folder or image, use

<?php
$client->get($object, $options)

If you are not authenticated, you will only be able to access public information.

The $object - Required

The object, referenced by $object in this and the next examples, is the user, image, album or folder object identifier you wish to query or modify.

The object can be specified in a number of ways:

  • Long form, as SmugMug documents and returns in all API responses:

    <?php
    $client->get('/api/v2/user/username!profile');
    
  • Short form, that is without the /api/v2/ part:

    <?php
    $client->get('user/username!profile');
    
  • Very short form, for the special !authuser and !siteuser:

    <?php
    $client->get('!authuser');
    

You can additionally pass filters in the $object path:

<?php
$client->get('user/username!profile?_filter=BioText,Facebook&_filteruri=User');

expansions:

<?php
$client->get('/api/v2/user/username?_expand=UserProfile')

… or perform multi-get queries:

<?php
$client->get('/api/v2/user/username1,username2?_filteruri=UserProfile');

The filters and expansions can also be passed in the $options instead if you prefer.

The GET $options - Optional

When querying the SmugMug API, you can optionally limit or increase the information SmugMug returns by passing additional optional options to each query. In the case of _verbosity and _shorturis, these options overrule those set when instantiating the client.

You can also use the $options array to pass any filters or expansions that use query parameters, like _filter or _expand. For example,

<?php
$options = [
    '_filter' => ['BioText', 'CoverImage'],
    '_filteruri' => ['User'],
    '_shorturis' => true,
    '_verbosity' => 2,
]
$client->get('user/username!profile', $options);

If you use the _expand option without setting _expandmethod to inline, SmugMug returns the expansions in their own object indexed by the expanded URI. To make things easier, phpSmug appends this object to the response object.

You can configure expansions using the _config option. You can pass this to phpSmug as part of the $options array as an array or JSON encoded string. If an array is received, phpSmug will JSON encode it for you else it’ll assume it has already been JSON encoded.

Making Changes

All changes to objects on SmugMug need to be made using the POST, PUT, PATCH or DELETE HTTP methods and you can do so as follows:

  • PATCH - Used to modify one or more data fields of an existing object, like changing the title of an image.

    <?php
    $client->patch($object, $options);
    
  • PUT - Used to edit all data fields of an existing object. This will replace all field with the information in this request.

    <?php
    $client->put($object, $options);
    
  • POST - Used for creating new objects, and for changes that aren’t as simple as directly editing a data field, like creating albums and folders, rotating and cropping images, and moving images between galleries.

    <?php
    $client->post($object, $options);
    
  • DELETE - Used for deleting objects.

    <?php
    $client->delete($object);
    

You can find more information about each of these methods at https://api.smugmug.com/api/v2/doc/tutorial/making-changes.html .

The $object - Required

The object, referenced by $object when making changes, is the user, image, album or folder object identifier you wish to modify and is accepted in all of the same forms as detailed above.

The PATCH, PUT, POST $options - Required

Unlike the GET options, the $options passed to the PATCH, PUT, and POST requests is required as without it, SmugMug won’t know what changes you wish to make to the object.

The options you pass are the “Owner-writeable” field for each object type as defined by SmugMug. For example, these album fields or these image fields. The full list of “Owner-writeable” field for each object type can be obtained by querying the OPTIONS for the object.

Probing the API

You can use the OPTIONS HTTP method to find out what other methods an endpoint supports and what parameters those methods accept.

You can query a particular object with:

<?php
$client->options($object);

If you set _verbosity to 3 in any query, this information will be returned in the response from SmugMug but not made immediately available within the response from that particular call. You can however grab the information from the raw response using $client->getResponse()->Options;. For example:

<?php
$client->get($object, array('_verbosity' => 3));
$client->getResponse()->Options;

Authentication

SmugMug’s API allows read-only unauthenticated access to all public information. If you need to access private information or make changes, you need to authorize your application.

SmugMug’s latest API only offers the option of using OAuth for authentication.

Authenticating using OAuth is a 3 step process.

Step 1: Obtain a Request Token

First, you need to request a request token:

<?php
$callback_url = "http://example.com/your/cool/app.php";
$request_token = $client->getRequestToken($callback_url);

The response will be an array containing the request token and secret. Store this in a location you can access later when it comes to requesting the access token.

The $callback_url is used to redirect the user back to your application once they’ve approved the access request.

Step 2: Direct the User to Authorize Your Application

Once you’ve obtained the request token, you need to use it to direct the user to SmugMug to authorize your application. You can do this in a variety of ways. It’s up to you as the application developer to choose which method suits you. Ultimately, you need to direct the user to https://secure.smugmug.com/services/oauth/1.0a/getRequestToken with the required Access, Permissions and the oauth_token query parameters.

phpSmug provides a simple method $client->getAuthorizeURL() that generates the URL you can use for redirection or for the user to click. It also takes care of passing the OAuth token too:

<?php
echo '<a href="'.$client->getAuthorizeURL().'">Authorize</a>';

If you don’t pass any options to this method, SmugMug’s default public read access is requested. If you need greater access or permissions, pass an array of the access or permissions you require:

<?php
$perms = [
    'Access' => 'Full',
    'Permissions' => 'Modify',
];
echo '<a href="'.$client->getAuthorizeURL($perms).'">Authorize</a>';

Once the user has authorized your application, they will be redirected back to the callback URL you used in getRequestToken() above with an additional oauth_verifier query parameter.

Step 3: Request the Access Token

Now you have the request token, oauth_verifier and your user has approved the access your application has requested, you need to request the access token using getAccessToken():

<?php
$client->setToken($request_token['oauth_token'], $request_token['oauth_token_secret']);  // Saved somewhere in step 1.
$oauth_verifier = $_GET['oauth_verifier'];  // This comes back with the callback request.
$access_token = $client->getAccessToken($oauth_verifier); // The results of this call is what your application needs to store indefinitely.

You will need to save the token and token secret returned by the getAccessToken() call in your own location for later use.

Once you’ve saved the token and token secret, you will no longer need to use any of the authentication methods above. Simply call $client->setToken(); and pass the token and secret immediately after instantiating your object instance.

For example:

<?php
$options = [
    'AppName' => 'My Cool App/1.0 (http://app.com)',
];
$client = new phpSmug\Client('[YOUR_API_KEY]', $options));
$client->setToken('[OAUTH_TOKEN]', '[OAUTH_TOKEN_SECRET]');
$albums = $client->get('user/[YOUR_USERNAME]!albums');

You can see how to implement this three step process into your own application in the example-oauth.php example.


Display Private Images

By default, when you create a new gallery within SmugMug, you will be able to display/embed the images from within this gallery on external websites. If you change the gallery settings and set “Visibility” set to “Private (Only Me)”, you will no longer be able to do that.

You can however use OAuth to sign your image URLs with your OAuth credentials using signResource() and display those images on an external site.

For example, you can display your private images using:

<?php
foreach ($images->AlbumImage as $image) {
    printf('<a href="%s"><img src="%s" title="%s" alt="%s" width="150" height="150" /></a>', $image->WebUri, $client->signResource($image->ThumbnailUrl), $image->Title, $image->ImageKey);
}

See the example-external-links.php for a complete implementation example.

Keep in mind, these links are time based so you will need to regenerate the links every time the page is loaded. This may affect the rendering performance of the page containing these signed images.


Uploading

Uploading is very easy. You can either upload an image from your local system, or from a location on the web.

In order to upload, you will need to have logged into SmugMug and have the album ID of the album you wish to upload to.

Then it’s just a matter of calling the method with the various optional parameters.

Whilst Guzzle supports asynchronous requests, phpSmug does not currently take advantage of this functionality so images can only be uploaded synchronously.

Upload a Local Image

<?php
# Optional options providing information about the image you're uploading.
$options = [
    'Altitude' => 1085,
    'Caption' => 'This is a photo from on top of Table Mountain',
    'FileName' => 'capetown.png',
    'Hidden' => false,
    'Keywords' => 'Cape Town; mountain; South Africa',
    'Latitude' => -34.045034,
    'Longitude' => 18.386065,
    'Pretty' => false,
    'Title' => 'From Table Mountain',
];

$response = $client->upload('album/r4nD0m', '/path/to/a/image.png', $options);

The $options you pass are all entirely optional and can be either in the short form shown above, or in the longer form SmugMug documents.

Upload an Image from a URL

Uploading from a URL is slightly different in that you don’t need to use the upload() method that uses a dedicated endpoint. Instead, you can POST to an album’s !uploadfromuri endpoint passing the URL and any additional options:

<?php
$options = [
    'AllowInsecure' => true,
    'Uri' => 'http://example.com/img/image.png',
    'Cookie' => 'foo',
    'Title' => 'Example.com Photo',
    'Caption' => 'This is a photo from example.com',
    'Hidden' => false,
    'FileName' => 'example.png',
    'Keywords' => 'example; photo',
];
$response = $client->post('album/r4nD0m!uploadfromuri', $options);

Uri (the source of the image) and Cookie (a string to send as the value of a Cookie header when fetching the source URI) are required options. AllowInsecure is required and must be set to true if the Uri is insecure.

Replacing Images

Replacing images is identical to uploading. The only difference is you need to specify the full ImageUri of the image you wish to replace.

For example,

<?php
$options = [
    'ImageUri' => '/api/v2/image/WxRHNQD-0',
];

$response = $client->upload('album/r4nD0m', '/path/to/a/replacement-image.png', $options);

Any other options provided will update those settings on the image.

You can’t replace an image by uploading from a URL.


Other Notes

Caching API Responses

Caching has been removed from phpSmug as the headers in the SmugMug API responses discourage caching and now phpSmug is using Guzzle, you can take advantage of much better Guzzle-friendly middleware implementations, like guzzle-cache-middleware, that better tie-in with the various frameworks you may already be using.

In order to use one of these middleware caching mechanisms, you’ll need to create and pass a handler stack with the cache middleware you plan to use when instantiating the phpSmug client. For example:

<?php
$handler_stack = HandlerStack::create();
$handler_stack->push(new YourChosenCachingMiddleware(), 'cache');
// Optional, but definitely nice to have, options
$options = [
    'AppName' => 'My Cool App/1.0 (http://app.com)',
    'handler' => $handler_stack,
];
$client = new phpSmug\Client('[YOUR_API_KEY]', $options));

Please refer to your chosen caching implementation documentation for further details on how to use and implement that side of things with Guzzle.

Access SmugMug via a Proxy

Accessing SmugMug with phpSmug through a proxy is possible by passing the proxy option when instantiating the client:

<?php
$options = [
    'AppName' => 'My Cool App/1.0 (http://app.com)',
    'proxy' => 'http://[proxy_address]:[port]',
];
$client = new phpSmug\Client('[YOUR_API_KEY]', $options));

All your requests will pass through the specified proxy on the specified port.

If you need a username and password to access your proxy, you can include them in the URL in the form: http://[username]:[password]@[proxy_address]:[port].

Examples

phpSmug comes with 3 examples to help get you on your way. All 3 examples perform the same thing, just using differing authentication methods. They all show thumbnails of the first album found for the respective authentication methods:

  • example.php illustrates anonymous, unauthenticated access.
  • example-oauth.php illustrates an OAuth login.
  • example-external-links.php illustrates displaying private images.

Reporting Issues

If you encounter a problem with phpSmug, please feel free to raise an issue. Please state which version of phpSmug you are using and ideally provide a small code snippet or link to a gist that can be used to reproduce the issue.

Getting Help

The best way to get help with implementing phpSmug into your projects is to open an issue. This allows you to easily search for other issues where others may have asked to the same questions or hit the same problems and if they haven’t, your issue will add to the resources available to others at a later date.

Please don’t be shy. If you’ve got a question, problem or are just curious about something, there’s a very good chance someone else is too, so go ahead and open an issue and ask.

If you need a quick bit of help or just want to say “Hi and thanks”, please use Twitter with the #phpSmug hashtag or tweet me directly @lildude.

Contributing

Found a bug or want to make phpSmug even better? Please feel free to open a pull request with your changes, but be sure to check out the CONTRIBUTING.md first for some tips and guidelines. No pull request is too small.

Changes

All notable changes to this project are documented in CHANGELOG.md.

License

MIT Licence phpSmug is licensed under the MIT License - see the LICENSE.md file for details