From 8bc23558b738f806b9786ec147a2cf1d4135fb39 Mon Sep 17 00:00:00 2001 From: Colin Seymour Date: Sat, 2 Mar 2013 11:46:56 +0000 Subject: [PATCH] Implemented signResource() to sign image urls with OAuth credentials. * Added ability to sign an image URL with OAuth authentication parameters to allow embedding of "non-external" images within external sites. Fixes Ticket #16. * Added example-external-links.php example to demonstrate the above. * Switched to using Markdown for the README file. * Misc other little coding changes and improvements. --- README.txt => README.md | 430 ++++++++++++++-------------- examples/example-external-links.php | 101 +++++++ examples/example-oauth.php | 9 +- phpSmug.php | 85 ++++-- 4 files changed, 379 insertions(+), 246 deletions(-) rename README.txt => README.md (51%) create mode 100644 examples/example-external-links.php diff --git a/README.txt b/README.md similarity index 51% rename from README.txt rename to README.md index 916f451..b89f467 100644 --- a/README.txt +++ b/README.md @@ -1,18 +1,17 @@ -phpSmug 3.4 - PHP Wrapper for the SmugMug API +phpSmug 3.5 - PHP Wrapper for the SmugMug API ============================================= -Written by Colin Seymour -Project Homepage: http://phpSmug.com/ +Written by Colin Seymour +Project Homepage: phpSmug is a PHP wrapper class for the SmugMug API and is based on work done by -Dan Coulter in phpFlickr (http://www.phpflickr.com) . +Dan Coulter in [phpFlickr](http://www.phpflickr.com) . -Released under GNU General Public License version 3 -(http://www.gnu.org/licenses/gpl.html) +Released under [GNU General Public License version 3](http://www.gnu.org/licenses/gpl.html) Copyright (C) 2008 Colin Seymour - This file is part of phpSmug. + This file is part of phpSmug. phpSmug is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -28,21 +27,25 @@ Copyright (C) 2008 Colin Seymour with phpSmug. If not, see . For more information about the class and upcoming tools and applications using -phpSmug, visit `http://phpsmug.com/'. +phpSmug, visit . Please help support the maintenance and development of phpSmug by making a -donation (http://phpsmug.com/donate). +[donation](http://phpsmug.com/donate). +-------------------------------------------------------------------------------- -What's New in phpSmug 3.4 + +What's New in phpSmug 3.5 ========================= -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. +phpSmug 3.5 introduces the ability for you to now embed images that are not marked +as externally linkable ("External links" is set to "No" within your SmugMug album +settings) into external websites by introducing a new method `signResource()`. + +See the Display Unlinkable Images section below for more details. +This README file is now in Markdown format instead of plaintext. Requirements @@ -57,10 +60,8 @@ optionally, curl support enabled. If you wish to use a database for caching, you will also need the following PEAR packages: - * MDB2 2.5.0b3 (http://pear.php.net/package/MDB2) or later. - - * The corresponding MDB2_Driver_* - (http://pear.php.net/search.php?q=MDB2_Driver&in=packages&setPerPage=20) + * [MDB2 2.5.0b3](http://pear.php.net/package/MDB2) or later. + * The corresponding [MDB2_Driver_*](http://pear.php.net/search.php?q=MDB2_Driver&in=packages&setPerPage=20) for the database you wish to use. Please consult the above links for details on installing the PEAR modules. @@ -88,12 +89,12 @@ create an instance. For example: The constructor takes up to five arguments depending on which SmugMug API endpoint and authentication mechanism you wish to use: - * `APIKey' - Required for ALL endpoints + * `APIKey` - **Required for ALL endpoints** This is the API key you have obtained for your application from - `http://www.smugmug.com/hack/apikeys'. + . - * `OAuthSecret' - Required for OAuth authentication (1.2.2 endpoint ONLY) + * `OAuthSecret` - **Required for OAuth authentication (1.2.2 endpoint ONLY)** Default: NULL This is the secret assigned to your API key and is displayed in the @@ -104,7 +105,7 @@ endpoint and authentication mechanism you wish to use: If you are not using OAuth authentication, then you don't need to worry about this argument. - * `AppName' - Optional + * `AppName` - Optional Default: NULL This is the name, version and URL of the application you have built using @@ -118,7 +119,7 @@ endpoint and authentication mechanism you wish to use: identify the application that is calling the API in the event one of your users reporting a problem on the SmugMug forums. - * `APIVer' - Optional + * `APIVer` - Optional Default: 1.2.0 Use this to set the endpoint you wish to use. The default is 1.2.0 as @@ -127,38 +128,38 @@ endpoint and authentication mechanism you wish to use: Arguments to all phpSmug methods must be provided as a series of strings or an associative array. For example: -Arguments as strings: +* *Arguments as strings:* - $f = new phpSmug("APIKey=12345678", - "AppName=My Cool App/1.0 (http://app.com)", - "APIVer=1.2.2"); + $f = new phpSmug("APIKey=12345678", + "AppName=My Cool App/1.0 (http://app.com)", + "APIVer=1.2.2"); -Arguments as an associative array: +* *Arguments as an associative array:* - $f = new phpSmug(array("APIKey" => "12345678", - "AppName" => "My Cool App/1.0 (http://app.com)", - "APIVer" => "1.2.2") - ); + $f = new phpSmug(array("APIKey" => "12345678", + "AppName" => "My Cool App/1.0 (http://app.com)", + "APIVer" => "1.2.2") + ); Naturally, you can predefine the array before instantiating the object and just pass the array variable. phpSmug implements all methods and arguments as documented in the SmugMug API -documentation (http://wiki.smugmug.net/display/SmugMug/API). +[documentation](http://wiki.smugmug.net/display/SmugMug/API). To call a method, remove the "smugmug." part of the name and replace any -fullstops with underscores. For example, instead of `smugmug.images.get', you -would call `images_get()'. +fullstops with underscores. For example, instead of `smugmug.images.get`, you +would call `images_get()`. -Remember: *ALL* function names and arguments *ARE* case sensitive. +Remember: **ALL** function names and arguments **ARE** case sensitive. -There is no need to pass the `SessionID' or `oauth_token*' arguments to the +There is no need to pass the `SessionID` or `oauth_token*` arguments to the various methods as phpSmug will automatically pass these, where applicable, unless otherwise documented. The exception is when using phpSmug to go through the OAuth authorization process detailed later. -`images_upload()' does not use the API for uploading, but instead HTTP PUT as -recommended by SmugMug at `http://wiki.smugmug.net/display/SmugMug/Uploading' +`images_upload()` does not use the API for uploading, but instead HTTP PUT as +recommended by SmugMug at HTTP PUT has been chosen as it's quicker, easier to use and more reliable than the other methods. @@ -174,7 +175,7 @@ With the release of version 1.2.2 of the SmugMug API, there are now two methods to authenticate with SmugMug: standard email/password or userid/hash or OAuth. phpSmug allows you to implement either method in your application. -Note: The 1.3.0 API endpoint only support OAuth authentication. +**Note: The 1.3.0 API endpoint only supports OAuth authentication.** @@ -183,7 +184,7 @@ Note: The 1.3.0 API endpoint only support OAuth authentication. This sets up your session ID required for interaction with the API using this authentication method. - `login()' without any arguments will log you in anonymously and will allow + `login()` without any arguments will log you in anonymously and will allow you to access any public gallery, image or sharegroup. If you wish to access private albums and images, upload or change @@ -205,7 +206,7 @@ Note: The 1.3.0 API endpoint only support OAuth authentication. Using a UserID and hash is probably the most secure method as your email and password can not be determined from the hash. However, in order to obtain the hash and UserID, you need to login at least once using - `login()' with the EmailAddress/Password combination. + `login()` with the EmailAddress/Password combination. @@ -217,53 +218,53 @@ Note: The 1.3.0 API endpoint only support OAuth authentication. Authenticating using OAuth is a 3 step process. - * First, you need to request an unauthorised request token: + * First, you need to request an unauthorised request token: - $resp = $f->auth_getRequestToken(); + $resp = $f->auth_getRequestToken(); - Once you've obtained the token, you need to use it to direct the user to - SmugMug to authorise 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 - `http://api.smugmug.com/services/oauth/authorize.mg' with the required - "Access", "Permissions" and the "oauth_token" arguments. + Once you've obtained the token, you need to use it to direct the user to + SmugMug to authorise 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 + with the required + "Access", "Permissions" and the "oauth_token" arguments. - phpSmug provides a simple method that generates a link you can use for - redirection or for the user to click (it also takes care of passing the - OAuth token too): + phpSmug provides a simple method that generates a link you can use for + redirection or for the user to click (it also takes care of passing the + OAuth token too): - echo 'Authorize'; + echo 'Authorize'; - "Public" and "Read" are the default options for Access and Permissions - respectively, so you can leave them out if you only need these permissions. + "Public" and "Read" are the default options for Access and Permissions + respectively, so you can leave them out if you only need these permissions. - Once the user has authorized your application, you will need to request - the access token and access token secret (once again phpSmug takes care of - passing the relevant OAuth token): + * Once the user has authorized your application, you will need to request + the access token and access token secret (once again phpSmug takes care of + passing the relevant OAuth token): - $token = $f->auth_getAccessToken(); + $token = $f->auth_getAccessToken(); - You will need to save the token and token secret returned by the - `auth_getAccessToken()' call in your own location for later use. + You will need to save the token and token secret returned by the + `auth_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 - `setToken("id=", "Secret=")' and pass the token ID and token - secret immediately after instantiating your object instance. + * Once you've saved the token and token secret, you will no longer need to + use any of the authentication methods above. Simply call + `setToken("id=", "Secret=")` and pass the token ID and token + secret immediately after instantiating your object instance. - For example: + For example: - $f = new phpSmug(array("APIKey" => "12345678", - "AppName" => "My Cool App/1.0 (http://app.com)", - "APIVer" => "1.2.2") - ); - $f->setToken("id=", "Secret="); + $f = new phpSmug(array("APIKey" => "12345678", + "AppName" => "My Cool App/1.0 (http://app.com)", + "APIVer" => "1.2.2") + ); + $f->setToken("id=", "Secret="); - By default, phpSmug uses the HMAC-SHA1 signature method. This is the most - secure signature method. If you wish to use PLAINTEXT, simply set the - `oauth_signature_method' class variable to `PLAINTEXT'. + By default, phpSmug uses the HMAC-SHA1 signature method. This is the most + secure signature method. If you wish to use PLAINTEXT, simply set the + `oauth_signature_method` class variable to `PLAINTEXT`. - $f->oauth_signature_method = 'PLAINTEXT'; + $f->oauth_signature_method = 'PLAINTEXT'; @@ -280,17 +281,17 @@ you just need to enable it. It is recommended that caching is enabled immediately after a new phpSmug instance is created, and before any other phpSmug methods are called. -To enable caching, use the `enableCache()' function. +To enable caching, use the `enableCache()` function. -The `enableCache()' function takes 4 arguments: +The `enableCache()` function takes 4 arguments: - * `type' - Required + * `type` - Required This is "db" for database or "fs" for filesystem. - * `dsn' - Required for type=db + * `dsn` - Required for type=db This a PEAR::MDB2 DSN connection string, for example: mysql://user:password@server/database @@ -299,13 +300,11 @@ The `enableCache()' function takes 4 arguments: database based caching. phpSmug does *NOT* supply the necessary PEAR modules. If you with to use a database for caching, you will need to download and install PEAR, the MDB2 PEAR module and the corresponding - database driver yourself. See MDB2 Manual - (http://pear.php.net/manual/en/package.database.mdb2.intro.php) for - details. + database driver yourself. See [MDB2 Manual](http://pear.php.net/manual/en/package.database.mdb2.intro.php) for details. - * `cache_dir' - Required for type=fs + * `cache_dir` - Required for type=fs This is the folder/directory that the web server has write access to. This directory must already exist. @@ -330,14 +329,14 @@ The `enableCache()' function takes 4 arguments: - * `cache_expire' - Optional + * `cache_expire` - Optional Default: 3600 This is the maximum age of each cache entry in seconds. - * `table' - Optional + * `table` - Optional Default: smugmug_cache This is the database table name that will be used for storing the cached @@ -357,7 +356,37 @@ Database based cache: $f->enableCache("type=db", "dsn=mysql://USERNAME:PASSWORD_database", "cache_expire=86400"); If you have caching enabled, and you make changes, it's a good idea to call -`clearCache()' to refresh the cache so your changes are reflected immediately. +`clearCache()` to refresh the cache so your changes are reflected immediately. + + + +Display Unlinkable Images +========================= + +**Note: This option is only available if you are using OAuth authentication.** + +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 "External links" to "No", you will no longer +be able to do that. + +If you are using OAuth authentication, you can however sign your image URLs with +your OAuth credentials using `signResource()` and display those images on an +external site. + +For example, you can display your "unlinkable" images using: + + + +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. + +As these links are time based, you won't be able to cache the HTML output, but you +can still use the caching mechanisms supplied with phpSmug to cache the raw API +data. @@ -403,17 +432,17 @@ Other Notes * By default, phpSmug will attempt to use Curl to communicate with the SmugMug API endpoint if it's available. If not, it will revert to using - sockets based communication using `fsockopen()'. If you wish to force the + sockets based communication using `fsockopen()`. If you wish to force the use of sockets, you can do so using the phpSmug supplied `setAdapter()' right after instantiating your instance: - $f = new phpSmug("APIKey="); + $f = new phpSmug("APIKey="); $f->setAdapter("socket"); Valid arguments are "curl" (default) and "socket". * Some people will need to use phpSmug from behind a proxy server. You can - use the `setProxy()' method to set the appropriate proxy settings. + use the `setProxy()` method to set the appropriate proxy settings. For example: @@ -424,7 +453,7 @@ Other Notes port. If your proxy server requires a username and password, then add those - options to the `setProxy()' method arguments too. + options to the `setProxy()` method arguments too. For example: @@ -435,19 +464,17 @@ Other Notes "password="); * By default phpSmug only uses HTTPS for authentication related methods like - all the `login*()' and `*Token()' methods. You can however force the use + all the `login*()` and `*Token()` methods. You can however force the use of HTTPS for ALL API calls, with the exception of uploads, by calling - `setSecureOnly()' immediately after instantiating the object. + `setSecureOnly()` immediately after instantiating the object. For example: - $f = new phpSmug("APIKey="); $f->setSecureOnly(); + $f = new phpSmug("APIKey="); + $f->setSecureOnly(); - NOTE: Forcing the use of HTTPS for ALL API communication may have an - impact on performance as HTTPS is inherently slower than HTTP NOTE: - phpSmug only implements this functionality for OAuth authenticated access. - The actual `login*()' methods will continue to use HTTPS, but none of the - other methods will if you authentication using basic login authentication. + **NOTE**: Forcing the use of HTTPS for ALL API communication may have an + impact on performance as HTTPS is inherently slower than HTTP. * If phpSmug encounters an error, or SmugMug returns a "Fail" response, an exception will be thrown and your application will stop executing. If @@ -460,8 +487,8 @@ Other Notes * SmugMug occasionally puts the SmugMug site into read-only mode in order to carry out maintenance. SmugMug's mode is now stored in the mode object - variable (eg `$f->mode' for easy checking of SmugMug's status. Note, this - is not set for `login()' methods as the API doesn't return the mode for + variable (eg `$f->mode` for easy checking of SmugMug's status. Note, this + is not set for `login()` methods as the API doesn't return the mode for logins because you can't login when SmugMug is in read-only mode. If SmugMug is not in read-only mode, this variable is empty. @@ -475,167 +502,138 @@ perform the same thing, just using differing authentication methods. They all show thumbnails of the first album found for the respective authentication methods: - * `example-login.php' illustrates a username/password login + * `example-login.php` illustrates a username/password login. + + * `example-anon.php` illustrates an anonymous login. - * `example-anon.php' illustrates an anonymous login + * `example-oauth.php` illustrates an OAuth login. - * `example-oauth.php' illustrates an OAuth login + * `example-external-links.php` illustrates displaying unlinkable images. You can see the anonymous and OAuth login examples in action at -`http://phpsmug.com/examples'. +. And that's all folks. Keep up to date on developments and enhancements to phpSmug on it's new -dedicated site at `http://phpsmug.com/'. +dedicated site at . If you encounter any problems with phpSmug, please check the list of known -issues with phpSmug and the API itself at `http://phpsmug.com/bugs'. If your -issue is not there, please leave a comment on the revision page at -`http://phpSmug.com/phpSmug-32'. +issues with phpSmug and the API itself at . If you are using phpSmug and wish to let the world know, drop me a line via the -contact form at `http://phpsmug.com/about' and I'll add a link and brief -description to the sidebar on `http://phpsmug.com/'. +contact form at or Tweet using the #phpSmug hashtag +and I'll add a link and brief description to the sidebar on . If you use and find phpSmug useful, please help support its maintenance and -development by making a donation (http://phpsmug.com/donate). +development by making a [donation](http://phpsmug.com/donate). -This document is also available online at `http://phpsmug.com/docs'. +This document is also available online at . Change History ============== - * 3.4 - 21 Jun '11 + * 3.5 - 2 Mar '13' + * Added ability to sign an image URL with OAuth authentication parameters + to allow embedding of "non-external" images within external sites. + Fixes Ticket #16. + * Added example-external-links.php example to demonstrate the above. + * Switched to using Markdown for the README file. - * Added missing hidden header for image uploads that should be hidden. - Fixes Ticket #12. + * 3.4 - 21 Jun '11 - * 3.3 - 3 Jun '11 + * Added missing hidden header for image uploads that should be hidden. + Fixes Ticket #12. + * 3.3 - 3 Jun '11 - * Worked around bizarre behaviour in the way PHP's implode() and - http_build_query() handle associative array keys with empty values. - Fixes Ticket #11. + * Worked around bizarre behaviour in the way PHP's `implode()` and + `http_build_query()` handle associative array keys with empty values. + Fixes Ticket #11. * 3.2 - 30 May '11 - - * Improved support for the 1.3.0 API endpoint (Ticket #10) - - * Implemented the ability to force all API communication to occur - securely over HTTPS. OAuth Only. (Ticket #9) - - * phpSmug now uses the documented secure.smugmug.com API endpoints - (Ticket #8) - - * Updated OAuth example to use new Album URL and to remove its use of - the deprecated session_unregister() PHP function. + * Improved support for the 1.3.0 API endpoint (Ticket #10) + * Implemented the ability to force all API communication to occur + securely over HTTPS. OAuth Only. (Ticket #9) + * phpSmug now uses the documented secure.smugmug.com API endpoints + (Ticket #8) + * Updated OAuth example to use new Album URL and to remove its use of + the deprecated `session_unregister()` PHP function. * 3.1 - 28 Mar '11 - - * 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 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 * 3.0 - 13 Nov '10 - - * The setProxy() method now allows you to set a proxy username and - password. - - * OAuth token setting now works correctly again (Ticket #7). - - * phpSmug no longer depends on PEAR so no longer ships any PEAR modules. - - * phpSmug is now 100% PHP 5 E_STRICT compliant (Ticket #2). - - * phpSmug is now licensed under the GPLv3 license. + * The `setProxy()` method now allows you to set a proxy username and + password. + * OAuth token setting now works correctly again (Ticket #7). + * phpSmug no longer depends on PEAR so no longer ships any PEAR modules. + * phpSmug is now 100% PHP 5 E_STRICT compliant (Ticket #2). + * phpSmug is now licensed under the GPLv3 license. * 2.2 - 21 Jul '10 - - * 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. (Ticket #6) - - * For my own benefit, I've now implemented a full PHPUnit test suite - that checks all functionality of phpSmug. + * 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. (Ticket #6) + * For my own benefit, I've now implemented a full PHPUnit test suite + that checks all functionality of phpSmug. * 2.1 - 27 Sep '09 - - * Changed image_upload method to upload to upload.smugmug.com instead - of api.smugmug.com. SmugMug made changes to enforce the use of - upload.smugmug.com as uploading to api.smugmug.com was causing - problems. (Ticket #5) - - * Resolved issue with recaching of cached data (Ticket #4). - - * SmugMug's mode (ie read-only etc) is now stored in $obj->mode for - easy checking of SmugMug's status. - - * Corrected "login with hash" example in the README file. + * Changed image_upload method to upload to upload.smugmug.com instead + of api.smugmug.com. SmugMug made changes to enforce the use of + upload.smugmug.com as uploading to api.smugmug.com was causing + problems. (Ticket #5) + * Resolved issue with recaching of cached data (Ticket #4). + * SmugMug's mode (ie read-only etc) is now stored in $obj->mode for + easy checking of SmugMug's status. + * Corrected "login with hash" example in the README file. * 2.0.2 - 22 Feb '09 - - * Tidied up code so phpSmug.php is E_STRICT compliant and doesn't - report any notice messages. - - * Force error log level to be lower than E_STRICT due to limitation of - PEAR modules (See notes in Ticket #2). - - * Resolved over-zealous clearCache() function (Ticket #3). + * Tidied up code so phpSmug.php is E_STRICT compliant and doesn't + report any notice messages. + * Force error log level to be lower than E_STRICT due to limitation of + PEAR modules (See notes in Ticket #2). + * Resolved over-zealous clearCache() function (Ticket #3). * 2.0.1 - 7 Nov '08 - - * Resolved issue where error code was not passed to Exception() line - 350 (Ticket #1) + * Resolved issue where error code was not passed to Exception() line + 350 (Ticket #1) * 2.0 - 30 Oct '08 - - * Removed die_on_error functionality in favour of exceptions - - * Remove getErrorCode() and getErrorMsg() functions as no longer - provide die_on_error functionality. Error codes and msgs are passed - via Exception. - - * Tidied up PEAR pkgs included to only include the bare minimum (these - are provided to ease implementation after all) - - * Updated HTTP_Request to 1.4.3 - - * Added OAuth support for 1.2.2 endpoint. Defaults to using HMAC-SHA1 - as it's the most secure with minimal perf issues. - - * Initial phpSmug 2.0 - Obsoletes ALL previous versions of phpSmug. - + * Removed `die_on_error` functionality in favour of exceptions + * Remove `getErrorCode()` and `getErrorMsg()` functions as no longer + provide `die_on_error` functionality. Error codes and msgs are passed + via Exception. + * Tidied up PEAR pkgs included to only include the bare minimum (these + are provided to ease implementation after all) + * Updated HTTP_Request to 1.4.3 + * Added OAuth support for 1.2.2 endpoint. Defaults to using HMAC-SHA1 + as it's the most secure with minimal perf issues. + * Initial phpSmug 2.0 - Obsoletes ALL previous versions of phpSmug. diff --git a/examples/example-external-links.php b/examples/example-external-links.php new file mode 100644 index 0000000..761b86b --- /dev/null +++ b/examples/example-external-links.php @@ -0,0 +1,101 @@ +. + */ +if (session_id() == "") { @session_start(); } +?> + + + phpSmug OAuth Login Example + + + +
+ +

phpSmug External Links Example

+signResource()". See line 91. + * + * This is how you can display images from galleries that have the + * "External links" gallery setting set to "No". + * + * You'll want to replace: + * - with one provided by SmugMug: http://www.smugmug.com/hack/apikeys + * - with your application name, version and URL + * - with the OAuth Secret associated with your API Key. + * + * The is NOT required, but it's encouraged as it will + * allow SmugMug diagnose any issues users may have with your application if + * they request help on the SmugMug forums. + * + */ +require_once( "../phpSmug.php" ); + +try { + $f = new phpSmug("APIKey=", "AppName=", "OAuthSecret="); + + // Perform the 3 step OAuth Authorisation process. + // NOTE: This is a very simplified example that does NOT store the final token. + // You will need to ensure your application does. + if ( ! isset( $_SESSION['SmugGalReqToken'] ) ) { + // Step 1: Get a Request Token + $d = $f->auth_getRequestToken(); + $_SESSION['SmugGalReqToken'] = serialize( $d ); + + // Step 2: Get the User to login to SmugMug and Authorise this demo + echo "

Click HERE to Authorize This Demo.

"; + echo "

A new window/tab will open asking you to login to SmugMug (if not already logged in). Once you've logged it, SmugMug will redirect you to a page asking you to approve the access (it's read only) to your public photos. Approve the request and come back to this page and click REFRESH below.

"; + echo "

REFRESH

"; + } else { + $reqToken = unserialize( $_SESSION['SmugGalReqToken'] ); + unset( $_SESSION['SmugGalReqToken'] ); + + // Step 3: Use the Request token obtained in step 1 to get an access token + $f->setToken("id={$reqToken['Token']['id']}", "Secret={$reqToken['Token']['Secret']}"); + $token = $f->auth_getAccessToken(); // The results of this call is what your application needs to store. + + // Set the Access token for use by phpSmug. + $f->setToken( "id={$token['Token']['id']}", "Secret={$token['Token']['Secret']}" ); + + // Get list of albums + $albums = $f->albums_get( 'Heavy=True' ); + // Get list of images and other useful information from the first gallery returned + $images = $f->images_get( "AlbumID={$albums['0']['id']}", "AlbumKey={$albums['0']['Key']}", "Heavy=1" ); + // Display the thumbnails and link to the Album page for each image. + // Each image is signed with your OAuth credentials. + foreach ( $images['Images'] as $image ) { + echo ''.$image['id'].''; + } + } +} +catch ( Exception $e ) { + echo "{$e->getMessage()} (Error Code: {$e->getCode()})"; +} +?> +
+ + diff --git a/examples/example-oauth.php b/examples/example-oauth.php index 5828bc6..4ef0041 100644 --- a/examples/example-oauth.php +++ b/examples/example-oauth.php @@ -33,12 +33,11 @@

phpSmug OAuth Login Example

with one provided by SmugMug: http://www.smugmug.com/hack/apikeys * - with your application name, version and URL diff --git a/phpSmug.php b/phpSmug.php index 3a20da2..716d22a 100644 --- a/phpSmug.php +++ b/phpSmug.php @@ -6,7 +6,7 @@ * without having to worry about the finer details of the API. * * @author Colin Seymour - * @version 3.4 + * @version 3.5 * @package phpSmug * @license GPL 3 {@link http://www.gnu.org/copyleft/gpl.html} * @copyright Copyright (c) 2008 Colin Seymour @@ -54,7 +54,7 @@ class PhpSmugException extends Exception {} * @package phpSmug **/ class phpSmug { - static $version = '3.4'; + static $version = '3.5'; private $cacheType = FALSE; var $SessionID; var $loginType; @@ -65,7 +65,6 @@ class phpSmug { var $oauth_token; var $mode; private $secure = false; - private $req; private $adapter = 'curl'; /** @@ -656,14 +655,14 @@ public function images_upload() if ( $this->loginType == 'authd' ) { $upload_req->setHeader( 'X-Smug-SessionID', $this->SessionID ); } else { - $upload_req->setHeader( 'Authorization', 'OAuth realm="http://api.smugmug.com/", - oauth_consumer_key="'.$this->APIKey.'", - oauth_token="'.$this->oauth_token.'", - oauth_signature_method="'.$this->oauth_signature_method.'", - oauth_signature="'.urlencode( $sig ).'", - oauth_timestamp="'.$this->oauth_timestamp.'", - oauth_version="1.0", - oauth_nonce="'.$this->oauth_nonce.'"' ); + $upload_req->setHeader( 'Authorization', 'OAuth realm="http://api.smugmug.com/",' + .'oauth_consumer_key="'.$this->APIKey.'",' + .'oauth_token="'.$this->oauth_token.'",' + .'oauth_signature_method="'.$this->oauth_signature_method.'",' + .'oauth_signature="'.urlencode( $sig ).'",' + .'oauth_timestamp="'.$this->oauth_timestamp.'",' + .'oauth_version="1.0",' + .'oauth_nonce="'.$this->oauth_nonce.'"' ); } $upload_req->setHeader( array( 'X-Smug-Version' => $this->APIVer, @@ -672,13 +671,10 @@ public function images_upload() 'X-Smug-Filename'=> basename($args['FileName'] ) ) ); // This is actually optional, but we may as well use what we're given /* Optional Headers */ - ( isset( $args['ImageID'] ) ) ? $upload_req->setHeader( 'X-Smug-ImageID', $args['ImageID'] ) : false; - ( isset( $args['Caption'] ) ) ? $upload_req->setHeader( 'X-Smug-Caption', $args['Caption'] ) : false; - ( isset( $args['Keywords'] ) ) ? $upload_req->setHeader( 'X-Smug-Keywords', $args['Keywords'] ) : false; - ( isset( $args['Latitude'] ) ) ? $upload_req->setHeader( 'X-Smug-Latitude', $args['Latitude'] ) : false; - ( isset( $args['Longitude'] ) ) ? $upload_req->setHeader( 'X-Smug-Longitude', $args['Longitude'] ) : false; - ( isset( $args['Altitude'] ) ) ? $upload_req->setHeader( 'X-Smug-Altitude', $args['Altitude'] ) : false; - ( isset( $args['Hidden'] ) ) ? $upload_req->setHeader( 'X-Smug-Hidden', $args['Hidden'] ) : false; + foreach( $args as $arg => $value ) { + if ( $arg == 'File' ) continue; + $upload_req->setHeader( 'X-Smug-' . $arg, $value ); + } //$proto = ( $this->oauth_signature_method == 'PLAINTEXT' || $this->secure ) ? 'https' : 'http'; // No secure uploads at this time. //$upload_req->setURL( $proto . '://upload.smugmug.com/'.$args['FileName'] ); @@ -806,12 +802,12 @@ private static function urlencodeRFC3986( $string ) * @param mixed $apiargs The arguments passed to the API method. * @return string **/ - private function generate_signature( $apicall, $apiargs = NULL ) + private function generate_signature( $apicall, $apiargs = NULL, $url = NULL ) { $this->oauth_timestamp = time(); $this->oauth_nonce = md5(time() . mt_rand()); - if ( $apicall != 'Upload' ) { + if ( !is_null( $apicall ) && $apicall != 'Upload' ) { if ( substr( $apicall,0,8 ) != 'smugmug.' ) { $apicall = 'smugmug.' . $apicall; } @@ -822,7 +818,9 @@ private function generate_signature( $apicall, $apiargs = NULL ) $this->oauth_signature_method = 'HMAC-SHA1'; $encKey = phpSmug::urlencodeRFC3986( $this->OAuthSecret ) . '&' . phpSmug::urlencodeRFC3986( $this->oauth_token_secret ); - if ( strpos( $apicall, 'Token' ) || $this->secure && $apicall != 'Upload' ) { + if ( is_null( $apicall ) && !is_null( $url ) ) { + $endpoint = $url; + } else if ( strpos( $apicall, 'Token' ) || $this->secure && $apicall != 'Upload' ) { $endpoint = "https://secure.smugmug.com/services/api/php/{$this->APIVer}/"; } else if ( $apicall == 'Upload' ) { //$proto = ( $this->oauth_signature_method == 'PLAINTEXT' || $this->secure ) ? 'https' : 'http'; @@ -832,7 +830,13 @@ private function generate_signature( $apicall, $apiargs = NULL ) $endpoint = "http://api.smugmug.com/services/api/php/{$this->APIVer}/"; } - $method = ( $apicall == 'Upload' ) ? 'PUT' : 'POST'; + if ( is_null( $apicall ) ) { + $method = 'GET'; + } else if ( $apicall == 'Upload' ) { + $method = 'PUT'; + } else { + $method = 'POST'; + } $params = array ( 'oauth_version' => '1.0', 'oauth_nonce' => $this->oauth_nonce, @@ -840,7 +844,7 @@ private function generate_signature( $apicall, $apiargs = NULL ) 'oauth_consumer_key' => $this->APIKey, 'oauth_signature_method' => $this->oauth_signature_method ); - if ( $apicall != 'Upload' ) $params = array_merge( $params, array('method' => $apicall ) ); + if ( !is_null( $apicall ) && $apicall != 'Upload' ) $params = array_merge( $params, array('method' => $apicall ) ); $params = ( !empty( $this->oauth_token ) ) ? array_merge( $params, array( 'oauth_token' => $this->oauth_token ) ) : $params; if ( $apicall != 'Upload' ) $params = ( !empty( $apiargs ) ) ? array_merge( $params, $apiargs ) : $params; $keys = array_map( array( 'phpSmug', 'urlencodeRFC3986' ), array_keys( $params ) ); @@ -885,7 +889,38 @@ private static function processArgs( $arguments ) } return $args; } - + + /** + * Sign the passed resource with the OAuth params. + * + * This essentially generates a signature for the passed URL and returns a + * string with the OAuth parameters and signature appended. + * + * This is very useful for allowing people to display images that are not set + * to allow external view within the gallery's settings on SmugMug. + * + * @param string $url The URL to the resource you wish to sign with the + * @access public + * @return string Signed URL + */ + public function signResource( $url ) + { + if ( $this->OAuthSecret ) { + $sig = $this->generate_signature( null, null, $url ); + $oauth_params = array ( + 'oauth_version' => '1.0', + 'oauth_nonce' => $this->oauth_nonce, + 'oauth_timestamp' => $this->oauth_timestamp, + 'oauth_consumer_key' => $this->APIKey, + 'oauth_signature_method' => $this->oauth_signature_method, + 'oauth_token' => $this->oauth_token, + 'oauth_signature' => $sig + ); + + // Build and return the query string. + return $url . '?' . http_build_query( $oauth_params ); + } + } } @@ -1295,7 +1330,7 @@ public function execute( $method, $url, $headers, $body, $config ) foreach ( $headers as $k => $v ) { $merged_headers[] = $k . ': ' . $v; } - + $ch = curl_init(); $options = array(