This is a PHP library that makes it easier to use the Roomstyler RESTful API. It is intended to be a wrapper for the API so that you, as user of the API will never have to write your own HTTP requests but instead can simply call a method to do it for you.
- Table of contents
- Installation
- Getting started
- Structure
- Errors
- API endpoints
- 3dplanner
Based on the roomstyler RESTful API, should anything be/remain unclear after reading the docs, check the documentation on there as well to see if it is more clear.
Also, this is not a 1-on-1 copy of the API, some method calls are grouped (render
for instance can do panorama
, hq
and 2d
aside from the default 3d
) or have a slightly more convenient way of adding parameters.
- Go to github.com/floorplanner/roomstyler-api-php
- Click on the
Clone or download
button - Select
Download ZIP
- Extract the
.zip
and move or copy it to the root of the project - Require
roomstyler-api-php-master/api/RoomstylerApi.php
in your application
~ $ cd project-root
project-root $ git clone [email protected]:floorplanner/roomstyler-api-php.git
This command clones the repository to project-root/roomstyler-api-php/
, to require it add:
<?php
require 'roomstyler-api-php/api/RoomstylerApi.php';
?>
~ $ cd composer-project-root
composer-project-root $ composer require floorplanner/roomstyler-api-php
When you want to read public data
<?php
require 'roomstyler-api-php/api/RoomstylerApi.php';
# can read all public data
$rsapi = new RoomstylerApi();
?>
For personal use, read global data or perform actions on rooms as the signed in user (whitelabel users can also login)
<?php
require 'roomstyler-api-php/api/RoomstylerApi.php';
# can read all public data
# can perform actions on rooms such as placing a comment or toggling a like
$rsapi = new RoomstylerApi(['user' => ['name' => 'myusername', 'password' => 'mypassword']]);
?>
For when you want to read global data and read, write or modify your own whitelabel data
<?php
require 'roomstyler-api-php/api/RoomstylerApi.php';
# can read all public data
# can read all whitelabel data
$rsapi = new RoomstylerApi(['whitelabel' => ['name' => 'mywhitelabel', 'password' => 'mywhitelabelpassword']]);
?>
For the those who want to maximize their integration potential, this allows you to read and write and modify data of your whitelabel and your own rooms and perform actions on rooms as the signed in user
<?php
require 'roomstyler-api-php/api/RoomstylerApi.php';
# can read all public data
# can read all whitelabel data
# can perform actions on rooms such as placing a comment or toggling a like
$rsapi = new RoomstylerApi(['user' => ['name' => 'myusername', 'password' => 'mypassword'],
'whitelabel' => ['name' => 'mywhitelabel', 'password' => 'mywhitelabelpassword']]);
?>
After doing this setup you should probably run a simple test to check if you can actually get a response back from a call.
<?php
# print the 5 latest rooms
echo '<pre>';
print_r($rsapi->rooms->index(['limit' => 5]));
echo '</pre>';
?>
We just talked about the user
and whitelabel
options that can be passed to the constructor of the RoomstylerApi
class but there are more options:
- protocol
- default:
https
Specify the default protocol
- default:
- whitelabel
- default:
[]
Logs in a whitelabel (discussed above)
- default:
- user
- default:
[]
Logs in a user (discussed above)
- default:
- host
- default:
roomstyler.com
The default hostname for the API
- default:
- prefix
- default:
api
The default namespace that prepends every request route e.g.rooms/10
=>api/rooms/10
- default:
- token
- default:
NULL
When you log in through theuser
option this property will be set to the server generated token
- default:
- timeout
- default:
5
Maximum number of seconds to allow cURL to execute a function
- default:
- language
- default:
en
Specify the editor language, supports:en
,fr
,de
,es
,nl
- default:
- connect_timeout
- default:
30
Maximum number of seconds to wait before connection times out (use 0 to wait indefinitely)
- default:
- request_headers
- default:
['Content-Type: application/json; charset=utf-8']
The default content type used to communicate with our API usingPOST
requests
- default:
- debug
- default:
false
Set to true to wrap results in an array containingresult
andrequest_info
which can be used to view the request
- default:
Everything is already setup to work with the API so you barely have to change these settings.
The option you'll most likely be using is debug
which allows you to take a peek into the request.
This is a general overview of the structure of the core objects behind the API, I will try to explain what you can do and when you can do it as best as I can. The API is OOP only, which means you're going to have to apply a little bit of PHP's OOP but don't worry, it'll be easy!
Starting with the RoomstylerApi
class, this is the base for the entire API.
It contains the settings and defaults that we've already discussed here
It also handles calls like this that you will be using:
#call to a new instance of "RoomstylerRoomMethods"
$api->rooms;
#call to a new instance of "RoomstylerComponentMethods"
$api->components;
If you're someone who has done OOP for some time and are familiar with PHP's magic methods
and more specifically the __get
magic method you'll know exactly what I'm talking about.
When you call something like ->components
on the $api
(Could be any variable name, must be an instance of the RoomstylerApi
class)
the $api
will look up a class with the name of RoomstylerComponentMethods
.
It does this by first converting whatever property you're trying to call to its singular form so components
becomes component
, then converting the first character to uppercase so component
becomes Component
and last but not least it prepends Roomstyler
and appends Methods
so that the final result becomes RoomstylerComponentMethods
.
If you're already using the singular form of a word, e.g. component
then the step to convert will do nothing and it will still uppercase the first character and prepend Roomstyler
and append Methods
This RoomstylerComponentMethods
class extends RoomstylerMethodBase
and allows you to call the documented component aggregation methods.
Essentially this means that you can call any property and get either an instance of a class back if it exists and is included, or a Fatal Error: Class 'Roomstyler[NonExistentClass]Methods' not found in...
.
This is the base class behind the scenes that allows you to use any and all of the RoomstylerApi->_settings
within an instance of Roomstyler[...]Methods
It's purpose is to provide a standard interface for actions you execute to get a dataset.
This is the base class behind the returned results from the requests. You use the methods in Roomstyler[...]Methods
to get a set of results (through some find()
, index()
or search()
action)
after which you get a single object or an array of objects back which you can then manipulate.
This base class is actually more useful than the RoomstylerMethodBase
since this one does the same and more, it also dynamically populates itself with properties returned from the API.
To get an idea of what I'm talking about, consider this json
response from api/users/972691
it should look something like this:
{
"id": 972691,
"username": "Sidney Liebrand",
"role": "admin",
"bio": "I'm a 21 year old web developer from the Netherlands, born, raised and still living in the always magnificent Dinteloord.",
"avatar": "https://d2sdvaauesfb7j.cloudfront.net/avatars/972691-1434979777.jpg",
"background": "https://d2sdvaauesfb7j.cloudfront.net/img/empty.jpeg"
}
And compare it to the return object that would look like this after a successful request and being __construct
ed
<?php
$api = new RoomstylerApi(['user' => $CONFIG['user_credentials']]);
$user = $api->user->find(972691);
echo '<pre>';
print_r($user);
# =>
RoomstylerUser Object
(
[_http_status:RoomstylerModelBase:private] => 200
[_accessible_props:RoomstylerModelBase:private] => ['errors']
[errors:RoomstylerModelBase:private] => RoomstylerError Object
(
)
[_settings:protected] => Array
(
[protocol] => https
[whitelabel] => Array
(
)
[user] => Array
(
[name] => [email protected]
[password] => mysignin_password
)
[host] => roomstyler.com
[prefix] => api
[token] => 64f97c9ee52df2735fsample-tokene6e252d58837d41b05cd
[timeout] => 5
[language] => en
[connect_timeout] => 30
[request_headers] => Array
(
[0] => Content-Type: application/json; charset=utf-8
)
[debug] =>
[user_agent] => RoomstylerApi/1.0 Type/normal (https://roomstyler.com)
)
[_whitelabeled:protected] =>
[id] => 972691
[username] => Sidney Liebrand
[role] => admin
[bio] => I'm a 21 year old web developer from the Netherlands, born, raised and still living in the always magnificent Dinteloord.
[avatar] => https://d2sdvaauesfb7j.cloudfront.net/avatars/972691-1434979777.jpg
[background] => https://d2sdvaauesfb7j.cloudfront.net/img/empty.jpeg
)
?>
Now all the properties that start with an underscore (_
) are also either :private
or :protected
which means we can't access them.
If you try accessing this freshly fetched users _whitelabel
property $user->_whitelabel
it would simply return Notice: Undefined property: RoomstylerUser::$_whitelabel
If you tried to access the public (and dynamically populated) id
on the other hand, you would get either NULL
or it's value if it's set.
The same goes for all other properties. Normally you would get a notice if you call a property that does not exist on an object ($user->non_existent_prop
): Notice: Undefined property: RoomstylerUser::$non_existent_prop
but since the fields are subject to change this would mean that you could get random Notice
errors for no reason.
Because of this, all properties that do not exist or aren't public (except errors
which is made public through __get
) will return NULL
.
The RoomstylerModelBase
class also provides us with some other methods we can use to see wether the object actually exists()
(not just an empty object - but actually having properties), or if the object in question has any errors
This is done (using our $user
initiated on top) by calling $user->errors
which will return a RoomstylerError
object or $user->exists()
to check if any property is set at all.
Every object returned from the API will have an accessible errors
property that has a few methods.
To check wether any of the objects contains any error (including http errors)
the maximum limit of the index call is 50. if this is exceeded the server will return a JSON error and an Unprocessable Entity (422) http error
$response = $rsapi->rooms->index(['limit' => 100]);
# full response
# since the API call errored, a single object is returned instead of an array of objects.
print_r($response);
# if this didn't happen, you'd have to call
print_r($response[0]);
# to see the errors (which are always bound to every returned object)
To access these errors, call the errors
property on a single entity.
It will return an instance of the RoomstylerError
class.
$response->errors
# => RoomstylerError{}
The RoomstylerError
class has three methods, one to get()
all the errors.
One to see if there are any()
errors and a function that loops through each()
error.
They will be explained using this example request.
(This request will error out since the max. limit for the index()
function is 50
)
$response = $rsapi->rooms->index(['limit' => 100]);
The any()
function will return true
if any errors including any http errors occured.
$response->errors->any();
# => true
The get()
function will return an array of errors including http errors.
If there are no errors, an empty array is returned.
The array returned is associative and will contain numeric and string keys.
As you might be able to see below, the errors have different depths making it hard to property loop the errors.
The solution for this is the builtin each()
method which is explained later.
$response->errors->get();
# => [0 => 'Some error', 'assoc' => 'too', 'user' => ['nested' => ['errors', 'for a single entity']]]
If there are errors, you can loop these through the each()
function.
It takes one parameter, which is a closure or callable function that itself takes one (optionally two) parameter(s)
The first parameter contains the error message of an error and the second parameter will contain it's parent keys if it was a nested hash.
As we know the above $response
example gives us two errors, one through a nested json object with an error
key which contains the error. And a http error since we're requesting too much data.
If we'd print the get()
function with this example, the errors array would look like this:
# => [
'error' => 'Limit should be between 1 and 50',
0 => 'Unprocessable entity'
]
Knowing the structure of the errors, if we build something like this:
$response->errors->each(function($error, $labels) {
if ($labels) $label = join('.', $labels);
else $label = 'default_label';
print_r($label": $error");
});
The output will look like this:
error: Limit should be between 1 and 50
default_label: Limit should be between 1 and 50
If the error
key wasn't an error but instead another hash with say a quantity
key containing the same error, the output for the same request would look like:
error.quantity: Limit should be between 1 and 50
default_label: Limit should be between 1 and 50
PHP snippet
<?php
print_r($rsapi->rooms->search_meta());
# => RoomstylerSearchMeta{}
?>
Method signature
RoomstylerRoomMethods->search_meta();
Parameters
- None
PHP snippet
<?php
print_r($rsapi->rooms->index());
# => [RoomstylerRoom{}, RoomstylerRoom{}, ...]
?>
Method signature
RoomstylerRoomMethods->index($params = []);
Parameters
$params
- Optional (Defaults do get set) - An array containing any the following keys:limit
- Optional (Default50
) - A number between (and including) 1 and 50page
- Optional (Default1
) - A number that defines the page you're on (useful for pagination)category
- Optional (seeRoomstylerSearchMeta
) - Filters results within specified categorylast_updated
- Optional - List rooms updated after a given timestampcreated
- Optional - List rooms created after a given timestampskip_last_updated
- Optional (Recommended, Defaulttrue
) - skips fetching last updated room, significantly speeds up requestsskip_total
- Optional (Recommended, Defaulttrue
) - skips fetching a count of all rooms, significantly speeds up requestsorder
- Optional - Order results based on a room attribute (see aRoomstylerRoom
object for a list of properties)direction
- Required iforder
specified - eitherasc
ordesc
user_id
- Optional - fetch rooms owned by this user (requires user access)whitelabel
- Optional - fetch rooms owned by your whitelabel (requires whitelabel access)tag
- Optional - Filter rooms by given tag
This method accepts the same parameters as the non-scoped index
method! The only difference is that the optional whitelabel
parameter is set to the whitelabel user for you
PHP snippet
<?php
# requires whitelabel access
print_r($rsapi->wl->rooms->index());
# => [RoomstylerRoom{}, RoomstylerRoom{}, ...]
?>
Method signature and parameters: see Fetching Rooms
PHP snippet
<?php
print_r($rsapi->rooms->find(123456));
# => RoomstylerRoom{}
?>
Method signature
RoomstylerRoomMethods->find($id);
Parameters
$id
- The id of the room to fetch
PHP snippet
<?php
print_r($rsapi->rooms->search(['q' => 'test']));
# => [RoomstylerRoom{}, RoomstylerRoom{}, ...]
?>
Method signature
RoomstylerRoomMethods->search($params = []);
Parameters
$params
- Optional (Defaults do get set) - An array containing any the following keys:q
- Required - A search stringlimit
- Optional (Default50
) - A number between (and including) 1 and 50page
- Optional (Default1
) - A number that defines the page you're on (useful for pagination)since
- Optional (seeRoomstylerSearchMeta
) - Filters results within specified timeframecategory
- Optional (seeRoomstylerSearchMeta
) - Filters results within specified categorystyle
- Optional (seeRoomstylerSearchMeta
) - Filters results within specified stylekind
- Optional - If it has the value ofown
it will search through the logged in users rooms (requires user access)
PHP snippet
<?php
print_r($rsapi->rooms->panoramas());
# => [RoomstylerRoom{}, RoomstylerRoom{}, ...]
?>
Method signature
RoomstylerRoomMethods->panoramas($params = ['limit' => 50, 'page' => 1]);
Parameters
$params
- Optional (Defaults do get set) - An array containing any the following keys:limit
- Optional (Default50
) - A number between (and including) 1 and 50page
- Optional (Default1
) - A number that defines the page you're on (useful for pagination)since
- Optional (seeRoomstylerSearchMeta
) - Filters results within specified timeframeskip_total
- Optional - skips counting of panorama's, speeds up request slightly iftrue
Lets say Let's initialize a $room
variable and use that in the following requests like so:
<?php $room = $rsapi->rooms->find(123456); ?>
PHP snippet
<?php
print_r($room->panorama());
# => RoomstylerRoomPanorama{}
?>
Method signature
RoomstylerRoom->panorama($params = []);
Parameters
$params
- Optional (Defaults do get set) - An array containing any the following keys:krpano_url
- When supplied, adds a krpano_url property containing a template url to use for rendering a cube image in krpano.
PHP snippet
<?php
# requires user access
print_r($room->comment('My awesome comment!'));
# => RoomstylerComment{}
?>
Method signature
RoomstylerRoom->comment($content);
Parameters
$content
- The comment text to be placed on the room
PHP snippet
<?php
# requires user access
print_r($room->toggle_love());
# => RoomstylerRoom{}
?>
Method signature
RoomstylerRoom->toggle_love();
Parameters
- None
PHP snippet
<?php
# requires whitelabel access
print_r($room->chown(972691));
# => RoomstylerComment{}
?>
Method signature
RoomstylerRoom->chown($user_id);
Parameters
$user_id
- The target user that will be the new owner of the subject room (should be a user(id) of your whitelabel)
PHP snippet
<?php
# requires whitelabel access
print_r($room->delete());
# => RoomstylerRoom{}
?>
Method signature
RoomstylerRoom->delete();
Parameters
- None
PHP snippet
<?php
print_r($room->products());
# => [RoomstylerProduct{}, RoomstylerProduct{}, ...]
?>
Method signature
RoomstylerRoom->products();
Parameters
- None
PHP snippet
<?php
print_r($room->loved_by());
# => [RoomstylerUser{}, RoomstylerUser{}, ...]
?>
Method signature
RoomstylerRoom->loved_by();
Parameters
- None
PHP snippet
<?php
print_r($room->related_rooms());
# => [RoomstylerRoom{}, RoomstylerRoom{}, ...]
?>
Method signature
RoomstylerRoom->related_rooms();
Parameters
- None
PHP snippet
<?php
print_r($room->comments());
# => [RoomstylerComment{}, RoomstylerComment{}, ...]
?>
Method signature
RoomstylerRoom->comment();
Parameters
- None
PHP snippet
<?php
print_r($room->add_tags(['first-tag', 'second-tag']));
# => RoomstylerRoom{}
?>
OR
<?php
print_r($room->add_tags('first-tag,second-tag'));
# => RoomstylerRoom{}
?>
Method signature
RoomstylerRoom->add_tags($tags)
Parameters
$tags
- Required - An array of individual tags or a string of comma-seperated tags
PHP snippet
<?php
print_r($room->remove_tags(['first-tag', 'second-tag']));
# => RoomstylerRoom{}
?>
OR
<?php
print_r($room->remove_tags('first-tag,second-tag'));
# => RoomstylerRoom{}
?>
Method signature
RoomstylerRoom->remove_tags($tags)
Parameters
$tags
- Required - An array of individual tags or a string of comma-seperated tags
PHP snippet
<?php
print_r($room->render());
# => RoomstylerRoom{}
?>
Method signature
RoomstylerRoom->render($mode = '', $params = [])
Parameters
$mode
- Optional (Either2d
,panorama
orhq
, any other strings will be ignored) - Specify rendering method, if left empty it will render in 3D, otherwise it will render either2d
,panorama
orhq
$params
- An array containing any the following keys:width
- Optional (Default value of960
for normal and2d
renders,1920
forhq
and ignored forpanorama
) - Width at which to render roomheight
- Optional (Default value of540
for normal and2d
renders,1920
forhq
and ignored forpanorama
) - Height at which to render roomsize
- Optional (Default value of1080
for panorama, ignored for the rest) - Size at which to render cube images for panoramacallback
- Optional (Required if$mode
is set to2d
.) - A callback url that will receive aPOST
request when rendering is done
PHP snippet
<?php
print_r($api->users->find(972691));
# => RoomstylerUser{}
?>
OR
<?php
print_r($api->users->find([972691, 972691]));
# => [RoomstylerUser{}, RoomstylerUser{}, ...]
?>
OR
<?php
print_r($api->users->find('972691, 972691'));
# => [RoomstylerUser{}, RoomstylerUser{}, ...]
?>
Method signature
RoomstylerUserMethods->find($ids)
Parameters
$ids
- Required - Theid
of a user, an array ofid
s or a string of comma seperatedid
s
PHP snippet
<?php
print_r($api->users->create(['email' => '[email protected]', 'username' => 'myusername', 'password' => 'mypassword']));
# => RoomstylerUser{}
?>
Method signature
RoomstylerUserMethods->create($params = [])
Parameters
$params
- Requiredemail
- Required - Email we want to use for this accountusername
- Requiredpassword
- Required
If you read over the user access setup section I showed an example of logging in as a user within the constructor
of the object.
It is however, also possible to login seperately like this, if You didn't login before and call this function manually later, all requests from then on will have
user access.
This function also returns the token needed to use in other requests such as to comment or love a room.
Also, if you're already logged in you do not need to use this function.
PHP snippet
<?php
print_r($api->users->login('[email protected]', 'mypassword'));
# => RoomstylerUser{}
?>
Method signature
RoomstylerUserMethods->login($email, $password)
Parameters
$email
- Required - Email to use$password
- Required - Password for the account
Let's initialize a $user
variable and use that in the following requests like so:
<?php $user = $rsapi->users->find(972691); ?>
Deletes a given user
PHP snippet
<?php
print_r($user->delete());
# => RoomstylerUser{}
?>
Method signature
RoomstylerUser->delete()
Parameters
- None
PHP snippet
<?php
print_r($user->loved_rooms());
# => [RoomstylerRoom{}, RoomstylerRoom{}, ...]
?>
Method signature
RoomstylerUser->loved_rooms($params = [])
Parameters
$params
- Optional (Defaults do get set) - An array containing any the following keys:page
- Optional - The page on which you're on (sets query offset to(page - 1) * per_page
)per_page
- Optional - The amount of results to display on a pageskip_total
- Optional (Defaulttrue
) - skips counting results, speeds up query slightly
PHP snippet
<?php
print_r($user->collections());
# => [RoomstylerCollection{}, RoomstylerCollection{}, ...]
?>
Method signature
RoomstylerUser->collections()
Parameters
- None
PHP snippet
<?php
print_r($user->collection(44));
# => RoomstylerCollection{}
?>
Method signature
RoomstylerUser->collection($id)
Parameters
$id
- Required - which of the users' collections to fetch
PHP snippet
<?php
print_r($api->contests->index());
# => [RoomstylerContest{}, RoomstylerContest{}, ...]
?>
Method signature
RoomstylerContestMethods->index($params = [])
Parameters
$params
- Optional (Defaults do get set) - An array containing any the following keys:per_page
- Optional (Default25
) - A number between (and including) 1 and 50page
- Optional (Default1
) - A number that defines the page you're on (useful for pagination)status
- Optional - Either"finished"
,"open"
or"vote"
title
- Optional - Return only contests where given string is contained within theirtitle
PHP snippet
<?php
print_r($api->contests->find(1317));
# => RoomstylerContest{}
?>
Method signature
RoomstylerContestMethods->find($id)
Parameters
$id
- Required - theid
of the contest to fetch
Let's initialize a $contest
variable and use that in the following requests like so:
<?php $contest = $rsapi->contests->find(1317); ?>
PHP snippet
<?php
print_r($contest->entries());
# => [RoomstylerContestEntry{}, RoomstylerContestEntry{}, ...]
?>
Method signature
RoomstylerContest->entries($params = [])
Parameters
$params
- Optional (Defaults do get set) - An array containing any the following keys:per_page
- Optional (Default25
) - A number between (and including) 1 and 50page
- Optional (Default1
) - A number that defines the page you're on (useful for pagination)order
- Optional - Attribute to order by and the direction to order byrand_seed
- Optional - If supplied, entries will be returned psuedo-random based on the seed (must be an integer)
Let's initialize a $contest_entry
variable and use that in the following requests like so:
<?php $contest_entry = $rsapi->contests->find(1317)->entries()[0]; ?>
PHP snippet
<?php
# requires user access
print_r($contest_entry->vote());
# => RoomstylerVote{}
?>
Method signature
RoomstylerContestEntry->vote()
Parameters
- None
PHP snippet
<?php
print_r($api->materials->find(3360));
# => RoomstylerMaterial{}
?>
Method signature
RoomstylerMaterialMethods->find($id)
Parameters
$id
- Required - theid
of the material item to fetch
PHP snippet
<?php
print_r($api->components->find('7b7e830978663ca44cafe62f095ee5f05af7670b'));
# => RoomstylerComponent{}
?>
Method signature
RoomstylerComponentMethods->find($id)
Parameters
$id
- Required - theid
of the component item to fetch
PHP snippet
<?php
print_r($api->categories->index());
# => [RoomstylerCategory{}, RoomstylerCategory{}, ...]
?>
Method signature
RoomstylerCategoryMethods->index()
Parameters
- None
PHP snippet
<?php
print_r($api->editor->embed());
# => <iframe...>
?>
Method signature
RoomstylerEditor->embed($opts = [], $html_opts = [])
Parameters
$opts
- Optional (Defaults do get set) - An array containing any the following keys:room_url
- Optional - Opens aroom_url
(returned from theRoomstylerRoom->url
property)token
- Optional - Log in a user through a tokenlanguage
- Optional - Set the language for the editor to use,en
,es
,nl
,fr
andde
login
- Optional - if false, prevents all logins
$html_opts
- Optional (Defaults do get set) - An array consisting of valid html attribute => value pairsframeborder
- Optional (Default0
) - HTML prop to hide the border around the editorwidth
- Optional (Default1024
) - Width of the editor iframeheight
- Optional (Default768
) - Height of the editor iframe