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:
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.
Requirements
- PHP >= 5.6.0,
- Guzzle 6 library and the Guzzle OAuth1 Subscriber,
- (optional) PHPUnit and php-cs-fixer to run tests.
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 likeMy 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 to2
. 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 tov2
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
phpSmug is licensed under the MIT License - see the LICENSE.md file for details