diff --git a/.gitignore b/.gitignore index bc08a82..f17b87a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,478 @@ +# Project specific files that should be ignored thingiverse_keys.php -index.php \ No newline at end of file +index.php + +##### Windows +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +##### Linux +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +##### MacOS +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +##### Backup +*.bak +*.gho +*.ori +*.orig +*.tmp + +##### GPG +secring.* + +##### Dropbox +# Dropbox settings and caches +.dropbox +.dropbox.attr +.dropbox.cache + +##### SynopsysVCS +# Waveform formats +*.vcd +*.vpd +*.evcd +*.fsdb + +# Default name of the simulation executable. A different name can be +# specified with this switch (the associated daidir database name is +# also taken from here): -o / +simv + +# Generated for Verilog and VHDL top configs +simv.daidir/ +simv.db.dir/ + +# Infrastructure necessary to co-simulate SystemC models with +# Verilog/VHDL models. An alternate directory may be specified with this +# switch: -Mdir= +csrc/ + +# Log file - the following switch allows to specify the file that will be +# used to write all messages from simulation: -l +*.log + +# Coverage results (generated with urg) and database location. The +# following switch can also be used: urg -dir .vdb +simv.vdb/ +urgReport/ + +# DVE and UCLI related files. +DVEfiles/ +ucli.key + +# When the design is elaborated for DirectC, the following file is created +# with declarations for C/C++ functions. +vc_hdrs.h + +##### SVN +.svn/ + +##### Mercurial +.hg/ +.hgignore +.hgsigs +.hgsub +.hgsubstate +.hgtags + +##### Bazaar +.bzr/ +.bzrignore + +##### CVS +/CVS/* +**/CVS/* +.cvsignore +*/.cvsignore + +##### TortoiseGit +# Project-level settings +/.tgitconfig + +##### PuTTY +# Private key +*.ppk + +##### Vim +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +##### Emacs +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + +##### SublimeText +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json +sftp-config-alt*.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +##### Notepad++ +# Notepad++ backups # +*.bak + +##### TextMate +*.tmproj +*.tmproject +tmtags + +##### VisualStudioCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +##### NetBeans +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +##### JetBrains +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +##### Eclipse +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +##### Dreamweaver +# DW Dreamweaver added files +_notes +_compareTemp +configs/ +dwsync.xml +dw_php_codehinting.config +*.mno + +##### CodeKit +# General CodeKit files to ignore +config.codekit +config.codekit3 +/min + +##### Gradle +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Composer +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +composer.lock + +##### PHP CodeSniffer +# gitignore for the PHP Codesniffer framework +# website: https://github.com/squizlabs/PHP_CodeSniffer +# +# Recommended template: PHP.gitignore + +/wpcs/* + +##### SASS +.sass-cache/ +*.css.map +*.sass.map +*.scss.map diff --git a/README.md b/README.md index b82587f..61bafd3 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -##Thingiverse +## Thingiverse A PHP wrapper for the Thingiverse API. -###Motivation +### Motivation Making awesome things easier! -##Use -###Configuration +## Use +### Configuration 1. Login at http://www.thingiverse.com/developers 2. Click on your app, then 'Edit this app' 3. In the thingiverse.php `__construct()` method, enter your Client ID and Client Secret (from the Thingiverse.com app page) into `$this->client_id` and `$this->client_secret` 4. Optionally enter your URL for Thingiverse to forward the user (and OAuth code) to in `$this->redirect_uri` -###Implementation +### Implementation 1. Import thingiverse.php `require_once 'thingiverse.php';` 2. Create a new instance `$thingiverse = new Thingiverse();`. Optionally enter an access token (if you have it) as a parameter (skip the next two steps if you do this) 3. Use `$thingiverse->makeLoginURL();` to create a link to authorize a user account for your app 4. Once you receive a code from Thingiverse, `$thingiverse->oAuth('code here');` 5. You're all set! -##License +## License The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/thingiverse.php b/thingiverse.php index 5bc0344..a3d6792 100644 --- a/thingiverse.php +++ b/thingiverse.php @@ -1,4 +1,5 @@ client_id = ''; - $this->client_secret = ''; - - // Optional, can also be set in Thingiverse app settings - $this->redirect_uri = ''; - - // Optional, if you already have your valid token. Otherwise, call oAuth(). - $this->access_token = $token; - } +class Thingiverse +{ + + const BASE_URL = 'https://api.thingiverse.com/'; + + public $access_token; + public $response_data; + public $response_code; + public $last_response_error; + + protected $client_id; + protected $client_secret; + protected $redirect_uri; + + protected $post_params = NULL; + protected $url = NULL; + + protected $available_licenses = array('cc', 'cc-sa', 'cc-nd', 'cc-nc-sa', 'cc-nc-nd', 'pd0', 'gpl', 'lgpl', 'bsd'); + + public function __construct($token = NULL) + { + // Required + $this->client_id = ''; + $this->client_secret = ''; + + // Optional, can also be set in Thingiverse app settings + $this->redirect_uri = ''; + + // Optional, if you already have your valid token. Otherwise, call oAuth(). + $this->access_token = $token; + } + + public function makeLoginURL() + { + $url = 'https://www.thingiverse.com/login/oauth/authorize?client_id=' . $this->client_id; + if (!empty($this->redirect_uri)) $url .= '&redirect_uri=' . $this->redirect_uri; + return $url; + } + + public function oAuth($code) + { + $this->url = 'https://www.thingiverse.com/login/oauth/access_token'; + $this->post_params['client_id'] = $this->client_id; + $this->post_params['client_secret'] = $this->client_secret; + $this->post_params['code'] = $code; + + $response = $this->_send('POST', TRUE); + + preg_match('/access_token=(\w+)&token_type/', $response, $match); + $this->access_token = $match[1]; + } + + protected function _send($type = 'GET', $is_oauth = FALSE) + { + if (empty($this->access_token) && !$is_oauth) exit('No access token.'); + if (empty($this->url)) exit('No URL.'); + + $curl = curl_init(); + + curl_setopt($curl, CURLOPT_URL, $this->url); + + $type = strtoupper($type); + switch ($type) { + case 'POST' : + case 'PATCH' : + case 'DELETE': + if (!$is_oauth) curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($this->post_params)); else + curl_setopt($curl, CURLOPT_POSTFIELDS, $this->post_params); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $type); + case 'GET': + break; + default: + exit("Invalid request type: '$type'."); + } + + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + + if (!$is_oauth) { + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $this->access_token, 'Content-Type: application/json')); + } + + curl_setopt($curl, CURLOPT_TIMEOUT, 10); + curl_setopt($curl, CURLOPT_HEADER, 1); + + $response = curl_exec($curl); + $this->response_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); + + $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); + $response_header = substr($response, 0, $header_size); + $response_body = substr($response, $header_size); + + if ($this->response_code != 200) { + if (preg_match('/x-error: (.+)/i', $response_header, $match)) $this->last_response_error = $match[1]; else + $this->last_response_error = 'No error given in header. Check response body.'; + } else + $this->last_response_error = ''; + + // Uncomment next four lines to see/debug full cURL response + // $curl_info = curl_getinfo($curl); + // var_dump($curl_info); + // var_dump($response_header); + // var_dump($response_body); + + curl_close($curl); + + $this->_reset(); + + if ($is_oauth) return $response_body; + + $this->response_data = json_decode($response_body); + + return $this->response_code; + } + + protected function _reset() + { + $this->post_params = NULL; + $this->url = NULL; + } + + public function getUser($username = 'me') + { + $this->url = self::BASE_URL . 'users/' . $username; + + return $this->_send(); + } + + public function updateUser($username, $bio = NULL, $location = NULL, $default_license = NULL, $full_name = NULL) + { + $this->url = self::BASE_URL . 'users/' . $username; + + if ($bio !== NULL) $this->post_params['bio'] = $bio; + if ($location !== NULL) $this->post_params['location'] = $location; + if ($default_license !== NULL && in_array($default_license, $this->available_licenses)) $this->post_params['default_license'] = $default_license; + if ($full_name !== NULL) $this->post_params['full_name'] = $full_name; + + return $this->_send('PATCH'); + } + + public function getUserThings($username = 'me') + { + $this->url = self::BASE_URL . 'users/' . $username . '/things'; + + return $this->_send(); + } + + public function getUserLikes($username = 'me') + { + $this->url = self::BASE_URL . 'users/' . $username . '/likes'; + + return $this->_send(); + } + + public function getUserCopies($username = 'me') + { + $this->url = self::BASE_URL . 'users/' . $username . '/copies'; + + return $this->_send(); + } + + public function getUserCollections($username = 'me') + { + $this->url = self::BASE_URL . 'users/' . $username . '/collections'; + + return $this->_send(); + } + + public function getUserDownloads($username = 'me') + { + $this->url = self::BASE_URL . 'users/' . $username . '/downloads'; + + return $this->_send(); + } + + public function followUser($username) + { + $this->url = self::BASE_URL . 'users/' . $username . '/followers'; + + return $this->_send('POST'); + } + + public function unfollowUser($username) + { + $this->url = self::BASE_URL . 'users/' . $username . '/followers'; + + return $this->_send('DELETE'); + } + + public function getThing($id) + { + $this->url = self::BASE_URL . 'things/' . $id; + + return $this->_send(); + } + + public function getThingImages($id, $image_id = NULL, $type = NULL, $size = NULL) + { + $this->url = self::BASE_URL . 'things/' . $id . '/images/'; + if ($image_id !== NULL) $this->url .= $image_id; + $query = array('type' => $type, 'size' => $size); + $string = http_build_query($query); + if (!empty($string)) { + $this->url .= '?' . $string; + } + + return $this->_send(); + } + + public function deleteThingImage($id, $image_id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/images/' . $image_id; + + return $this->_send('DELETE'); + } + + public function getThingFiles($id, $file_id = NULL) + { + $this->url = self::BASE_URL . 'things/' . $id . '/files/'; + if ($file_id !== NULL) $this->url .= $file_id; + + return $this->_send(); + } + + public function deleteThingFile($id, $file_id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/files/' . $file_id; + + return $this->_send('DELETE'); + } + + public function getThingLikes($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/likes'; + + return $this->_send(); + } + + public function getThingAncestors($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/ancestors'; + + return $this->_send(); + } + + public function getThingDerivatives($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/derivatives'; + + return $this->_send(); + } + + public function getThingTags($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/tags'; + + return $this->_send(); + } + + public function getThingCategory($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/categories'; + + return $this->_send(); + } + + public function updateThing($id, $name = NULL, $license = NULL, $category = NULL, $description = NULL, $instructions = NULL, $is_wip = NULL, $tags = NULL) + { + $this->url = self::BASE_URL . 'things/' . $id; + + if ($name !== NULL) $this->post_params['name'] = $name; + if ($license !== NULL && in_array($license, $this->available_licenses)) $this->post_params['license'] = $license; + if ($category !== NULL) $this->post_params['category'] = $category; + if ($description !== NULL) $this->post_params['description'] = $description; + if ($instructions !== NULL) $this->post_params['instructions'] = $instructions; + if ($is_wip !== NULL && is_bool($is_wip)) $this->post_params['is_wip'] = $is_wip; + if ($tags !== NULL && is_array($tags)) $this->post_params['tags'] = $tags; + + return $this->_send('PATCH'); + } + + public function createThing($name, $license, $category, $description = NULL, $instructions = NULL, $is_wip = NULL, $tags = NULL, $ancestors = NULL) + { + $this->url = self::BASE_URL . 'things/'; + + $this->post_params['name'] = $name; + + if (in_array($license, $this->available_licenses)) $this->post_params['license'] = $license; else + return 'Not a valid license.'; + + $this->post_params['category'] = $category; + if ($description !== NULL) $this->post_params['description'] = $description; + if ($instructions !== NULL) $this->post_params['instructions'] = $instructions; + if ($is_wip !== NULL && is_bool($is_wip)) $this->post_params['is_wip'] = $is_wip; + if ($tags !== NULL && is_array($tags)) $this->post_params['tags'] = $tags; + if ($ancestors !== NULL && is_array($ancestors)) $this->post_params['ancestors'] = $ancestors; + + return $this->_send('POST'); + } + + public function deleteThing($id) + { + $this->url = self::BASE_URL . 'things/' . $id; + + return $this->_send('DELETE'); + } + + public function uploadThingFile($id, $filename) + { + $this->url = self::BASE_URL . 'things/' . $id . '/files'; + + $this->post_params['filename'] = $filename; + + return $this->_send('POST'); + } + + public function publishThing($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/publish'; + + return $this->_send('POST'); + } + + public function getThingCopies($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/copies'; + + return $this->_send(); + } + + public function uploadThingCopyImage($id, $filename) + { + $this->url = self::BASE_URL . 'things/' . $id . '/copies'; - public function makeLoginURL() - { - $url = 'https://www.thingiverse.com/login/oauth/authorize?client_id=' . $this->client_id; - if ( ! empty($this->redirect_uri)) - $url .= '&redirect_uri=' . $this->redirect_uri; - return $url; - } - - public function oAuth($code) - { - $this->url = 'https://www.thingiverse.com/login/oauth/access_token'; - $this->post_params['client_id'] = $this->client_id; - $this->post_params['client_secret'] = $this->client_secret; - $this->post_params['code'] = $code; - - $response = $this->_send('POST', TRUE); - - preg_match('/access_token=(\w+)&token_type/', $response, $match); - $this->access_token = $match[1]; - } - - public function getUser($username = 'me') - { - $this->url = self::BASE_URL . 'users/' . $username; - - return $this->_send(); - } - - public function updateUser($username, $bio = NULL, $location = NULL, $default_license = NULL, $full_name = NULL) - { - $this->url = self::BASE_URL . 'users/' . $username; - - if ($bio !== NULL) - $this->post_params['bio'] = $bio; - if ($location !== NULL) - $this->post_params['location'] = $location; - if ($default_license !== NULL && in_array($default_license, $this->available_licenses)) - $this->post_params['default_license'] = $default_license; - if ($full_name !== NULL) - $this->post_params['full_name'] = $full_name; - - return $this->_send('PATCH'); - } - - public function getUserThings($username = 'me') - { - $this->url = self::BASE_URL . 'users/' . $username . '/things'; - - return $this->_send(); - } - - public function getUserLikes($username = 'me') - { - $this->url = self::BASE_URL . 'users/' . $username . '/likes'; - - return $this->_send(); - } - - public function getUserCopies($username = 'me') - { - $this->url = self::BASE_URL . 'users/' . $username . '/copies'; - - return $this->_send(); - } - - public function getUserCollections($username = 'me') - { - $this->url = self::BASE_URL . 'users/' . $username . '/collections'; - - return $this->_send(); - } - - public function getUserDownloads($username = 'me') - { - $this->url = self::BASE_URL . 'users/' . $username . '/downloads'; - - return $this->_send(); - } - - public function followUser($username) - { - $this->url = self::BASE_URL . 'users/' . $username . '/followers'; - - return $this->_send('POST'); - } - - public function unfollowUser($username) - { - $this->url = self::BASE_URL . 'users/' . $username . '/followers'; - - return $this->_send('DELETE'); - } - - public function getThing($id) - { - $this->url = self::BASE_URL . 'things/' . $id; - - return $this->_send(); - } - - public function getThingImages($id, $image_id = NULL, $type = NULL, $size = NULL) - { - $this->url = self::BASE_URL . 'things/' . $id . '/images/'; - if ($image_id !== NULL) - $this->url .= $image_id; - $query = array( - 'type' => $type, - 'size' => $size - ); - $string = http_build_query($query); - if ( ! empty($string)) { - $this->url .= '?' . $string; - } - - return $this->_send(); - } - - public function deleteThingImage($id, $image_id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/images/' . $image_id; - - return $this->_send('DELETE'); - } - - public function getThingFiles($id, $file_id = NULL) - { - $this->url = self::BASE_URL . 'things/' . $id . '/files/'; - if ($file_id !== NULL) - $this->url .= $file_id; - - return $this->_send(); - } - - public function deleteThingFile($id, $file_id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/files/' . $file_id; - - return $this->_send('DELETE'); - } - - public function getThingLikes($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/likes'; - - return $this->_send(); - } - - public function getThingAncestors($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/ancestors'; - - return $this->_send(); - } - - public function getThingDerivatives($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/derivatives'; - - return $this->_send(); - } - - public function getThingTags($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/tags'; - - return $this->_send(); - } - - public function getThingCategory($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/categories'; - - return $this->_send(); - } - - public function updateThing($id, $name = NULL, $license = NULL, $category = NULL, $description = NULL, $instructions = NULL, $is_wip = NULL, $tags = NULL) - { - $this->url = self::BASE_URL . 'things/' . $id; - - if ($name !== NULL) - $this->post_params['name'] = $name; - if ($license !== NULL && in_array($license, $this->available_licenses)) - $this->post_params['license'] = $license; - if ($category !== NULL) - $this->post_params['category'] = $category; - if ($description !== NULL) - $this->post_params['description'] = $description; - if ($instructions !== NULL) - $this->post_params['instructions'] = $instructions; - if ($is_wip !== NULL && is_bool($is_wip)) - $this->post_params['is_wip'] = $is_wip; - if ($tags !== NULL && is_array($tags)) - $this->post_params['tags'] = $tags; - - return $this->_send('PATCH'); - } - - public function createThing($name, $license, $category, $description = NULL, $instructions = NULL, $is_wip = NULL, $tags = NULL, $ancestors = NULL) - { - $this->url = self::BASE_URL . 'things/'; - - $this->post_params['name'] = $name; - - if (in_array($license, $this->available_licenses)) - $this->post_params['license'] = $license; - else - return 'Not a valid license.'; + $this->post_params['filename'] = $filename; - $this->post_params['category'] = $category; - if ($description !== NULL) - $this->post_params['description'] = $description; - if ($instructions !== NULL) - $this->post_params['instructions'] = $instructions; - if ($is_wip !== NULL && is_bool($is_wip)) - $this->post_params['is_wip'] = $is_wip; - if ($tags !== NULL && is_array($tags)) - $this->post_params['tags'] = $tags; - if ($ancestors !== NULL && is_array($ancestors)) - $this->post_params['ancestors'] = $ancestors; + return $this->_send('POST'); + } - return $this->_send('POST'); - } + public function likeThing($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/likes'; - public function deleteThing($id) - { - $this->url = self::BASE_URL . 'things/' . $id; + return $this->_send('POST'); + } - return $this->_send('DELETE'); - } + public function deleteLike($id) + { + $this->url = self::BASE_URL . 'things/' . $id . '/likes'; - public function uploadThingFile($id, $filename) - { - $this->url = self::BASE_URL . 'things/' . $id . '/files'; + return $this->_send('DELETE'); + } - $this->post_params['filename'] = $filename; + public function getFile($id) + { + $this->url = self::BASE_URL . 'files/' . $id; - return $this->_send('POST'); - } + return $this->_send(); + } - public function publishThing($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/publish'; + public function finalizeFile($id) + { + $this->url = self::BASE_URL . 'files/' . $id . '/finalize'; - return $this->_send('POST'); - } + return $this->_send('POST'); + } - public function getThingCopies($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/copies'; + public function getCopies($id = NULL) + { + $this->url = self::BASE_URL . 'copies'; - return $this->_send(); - } + if ($id !== NULL) $this->url .= '/' . $id; - public function uploadThingCopyImage($id, $filename) - { - $this->url = self::BASE_URL . 'things/' . $id . '/copies'; + return $this->_send(); + } - $this->post_params['filename'] = $filename; + public function getCopyImages($id) + { + $this->url = self::BASE_URL . 'copies/' . $id . '/images'; - return $this->_send('POST'); - } + return $this->_send(); + } - public function likeThing($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/likes'; + public function deleteCopy($id) + { + $this->url = self::BASE_URL . 'copies/' . $id; - return $this->_send('POST'); - } + return $this->_send('DELETE'); + } - public function deleteLike($id) - { - $this->url = self::BASE_URL . 'things/' . $id . '/likes'; + public function getCollections($id = NULL) + { + $this->url = self::BASE_URL . 'collections'; - return $this->_send('DELETE'); - } + if ($id !== NULL) $this->url .= '/' . $id; - public function getFile($id) - { - $this->url = self::BASE_URL . 'files/' . $id; + return $this->_send(); + } - return $this->_send(); - } + public function getCollectionThings($id) + { + $this->url = self::BASE_URL . 'collections/' . $id . '/things'; - public function finalizeFile($id) - { - $this->url = self::BASE_URL . 'files/' . $id . '/finalize'; + return $this->_send(); + } - return $this->_send('POST'); - } + public function createCollection($name, $description = NULL) + { + $this->url = self::BASE_URL . 'collections/'; - public function getCopies($id = NULL) - { - $this->url = self::BASE_URL . 'copies'; + $this->post_params['name'] = $name; + if ($description !== NULL) $this->post_params['description'] = $description; - if ($id !== NULL) - $this->url .= '/'.$id; + return $this->_send('POST'); + } - return $this->_send(); - } + public function addCollectionThing($id, $thing_id, $description = NULL) + { + $this->url = self::BASE_URL . 'collections/' . $id . '/thing/' . $thing_id; + if ($description !== NULL) $this->post_params['description'] = $description; - public function getCopyImages($id) - { - $this->url = self::BASE_URL . 'copies/' . $id . '/images'; + return $this->_send('POST'); + } - return $this->_send(); - } + public function deleteCollectionThing($id, $thing_id) + { + $this->url = self::BASE_URL . 'collections/' . $id . '/thing/' . $thing_id; - public function deleteCopy($id) - { - $this->url = self::BASE_URL . 'copies/' . $id; + return $this->_send('DELETE'); + } - return $this->_send('DELETE'); - } + public function updateCollection($id, $name, $description = NULL) + { + $this->url = self::BASE_URL . 'collections/' . $id; - public function getCollections($id = NULL) - { - $this->url = self::BASE_URL . 'collections'; + $this->post_params['name'] = $name; + if ($description !== NULL) $this->post_params['description'] = $description; - if ($id !== NULL) - $this->url .= '/'.$id; + return $this->_send('PATCH'); + } - return $this->_send(); - } + public function deleteCollection($id) + { + $this->url = self::BASE_URL . 'collections/' . $id; - public function getCollectionThings($id) - { - $this->url = self::BASE_URL . 'collections/' . $id . '/things'; + return $this->_send('DELETE'); + } - return $this->_send(); - } + public function getNewest() + { + $this->url = self::BASE_URL . 'newest/'; - public function createCollection($name, $description = NULL) - { - $this->url = self::BASE_URL . 'collections/'; + return $this->_send(); + } - $this->post_params['name'] = $name; - if ($description !== NULL) - $this->post_params['description'] = $description; + public function getPopular() + { + $this->url = self::BASE_URL . 'popular/'; - return $this->_send('POST'); - } + return $this->_send(); + } - public function addCollectionThing($id, $thing_id, $description = NULL) - { - $this->url = self::BASE_URL . 'collections/' . $id . '/thing/' . $thing_id; - if ($description !== NULL) - $this->post_params['description'] = $description; + public function getFeatured($return_complete = FALSE) + { + $this->url = self::BASE_URL . 'featured/'; + $this->url .= ($return_complete) ? '?return=complete' : ''; - return $this->_send('POST'); - } + return $this->_send(); + } - public function deleteCollectionThing($id, $thing_id) - { - $this->url = self::BASE_URL . 'collections/' . $id . '/thing/' . $thing_id; + public function search($term) + { + $this->url = self::BASE_URL . 'search/' . urlencode($term); - return $this->_send('DELETE'); - } + return $this->_send(); + } - public function updateCollection($id, $name, $description = NULL) - { - $this->url = self::BASE_URL . 'collections/' . $id; + public function getCategories($id = NULL) + { + $this->url = self::BASE_URL . 'categories'; - $this->post_params['name'] = $name; - if ($description !== NULL) - $this->post_params['description'] = $description; + if ($id !== NULL) $this->url .= '/' . $id; - return $this->_send('PATCH'); - } + return $this->_send(); + } - public function deleteCollection($id) - { - $this->url = self::BASE_URL . 'collections/' . $id; + public function getCategoryThings($id) + { + $this->url = self::BASE_URL . 'categories/' . $id . '/things'; - return $this->_send('DELETE'); - } + return $this->_send(); + } - public function getNewest() - { - $this->url = self::BASE_URL . 'newest/'; + public function getTagThings($tag) + { + $this->url = self::BASE_URL . 'tags/' . $tag . '/things'; - return $this->_send(); - } + return $this->_send(); + } - public function getPopular() - { - $this->url = self::BASE_URL . 'popular/'; + public function getTags($tag = NULL) + { + $this->url = self::BASE_URL . 'tags/'; - return $this->_send(); - } + if ($tag !== NULL) $this->url .= $tag; - public function getFeatured($return_complete = FALSE) - { - $this->url = self::BASE_URL . 'featured/'; - $this->url .= ($return_complete) ? '?return=complete' : ''; - - return $this->_send(); - } - - public function search($term) - { - $this->url = self::BASE_URL . 'search/' . urlencode($term); - - return $this->_send(); - } - - public function getCategories($id = NULL) - { - $this->url = self::BASE_URL . 'categories'; - - if ($id !== NULL) - $this->url .= '/'.$id; - - return $this->_send(); - } - - public function getCategoryThings($id) - { - $this->url = self::BASE_URL . 'categories/' . $id . '/things'; - - return $this->_send(); - } - - public function getTagThings($tag) - { - $this->url = self::BASE_URL . 'tags/' . $tag . '/things'; - - return $this->_send(); - } - - public function getTags($tag = NULL) - { - $this->url = self::BASE_URL . 'tags/'; - - if ($tag !== NULL) - $this->url .= $tag; - - return $this->_send(); - } - - protected function _reset() - { - $this->post_params = NULL; - $this->url = NULL; - } - - protected function _send($type = 'GET', $is_oauth = FALSE) - { - if (empty($this->access_token) && ! $is_oauth) - exit('No access token.'); - if (empty($this->url)) - exit('No URL.'); - - $curl = curl_init(); - - curl_setopt($curl, CURLOPT_URL, $this->url); - - $type = strtoupper($type); - switch ($type) - { - case 'POST' : - case 'PATCH' : - case 'DELETE': - if ( ! $is_oauth) - curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($this->post_params)); - else - curl_setopt($curl, CURLOPT_POSTFIELDS, $this->post_params); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $type); - case 'GET': - break; - default: - exit("Invalid request type: '$type'."); - } - - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - - if ( ! $is_oauth) - { - curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $this->access_token, 'Content-Type: application/json')); - } - - curl_setopt($curl, CURLOPT_TIMEOUT, 10); - curl_setopt($curl, CURLOPT_HEADER, 1); - - $response = curl_exec($curl); - $this->response_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - - $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); - $response_header = substr($response, 0, $header_size); - $response_body = substr($response, $header_size); - - if ($this->response_code != 200) - { - if (preg_match('/x-error: (.+)/i', $response_header, $match)) - $this->last_response_error = $match[1]; - else - $this->last_response_error = 'No error given in header. Check response body.'; - } - else - $this->last_response_error = ''; - - // Uncomment next four lines to see/debug full cURL response - // $curl_info = curl_getinfo($curl); - // var_dump($curl_info); - // var_dump($response_header); - // var_dump($response_body); - - curl_close($curl); - - $this->_reset(); - - if ($is_oauth) - return $response_body; - - $this->response_data = json_decode($response_body); - - return $this->response_code; - } + return $this->_send(); + } }