Converting shoucast statistics - php

I have this script to check the song title and streamname (DJ) listeners but it doesn't always work like it should
it should be if status 1 show what the stats grab else show offline. but it doesn't want to work, I got this code off a friend he doesn't want to recode it but I have no idea how to make it work with shoutcast 2.0
heres the code
<?php
class radioStuff {
/**
Shoutcast specific class to grab server stats
*/
private $url = "http://sc.*REMOVED*.co.uk";
private $port = 80;
private $json_object;
public function __construct() {
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$this->url . ':' . $this->port . '/stats?json=1');
// Execute
$result=curl_exec($ch);
// Closing
curl_close($ch);
$this->json_object = json_decode($result);
}
public function getHabboUrl() {
$imageString = 'http://www.habbo.com/habbo-imaging/avatarimage?user=' . $this->json_object->servergenre . '&direction=4&head_direction=3&action=wlk&gesture=sml';
return $imageString;
}
public function getCurrentListeners() {
return $this->json_object->currentlisteners;
}
public function getSTATUS() {
return $this->json_object->streamstatus;
}
public function getCurrentDJ() {
return $this->json_object->servertitle;
}
public function getCurrentSong() {
return $this->json_object->songtitle;
}
}
$radio = new radioStuff();
if($radio->getSTATUS == 1) {
$response = array(
'dj' => 'Radio statistics are offline!',
'song' => 'We are offline!', 'listeners' => ''
);
header('Content-Type: application/json');
echo json_encode($response);
} else {
$response = array(
'dj' => $radio->getCurrentDJ(),
'song' => $radio->getCurrentSong(),
'listeners' => $radio->getCurrentListeners()
);
header('Content-Type: application/json');
echo json_encode($response);
}

You have an error in you code:
if($radio->getSTATUS == 1) {
should be
if($radio->getSTATUS() == 1) {
getSTATUS is a function, so you should call it with ()
Also, if stream status is 1 - the stream is alive and if stream status is 0 - then your station is offline, so replace 1 with 0 in your comparison.

Related

PHP Curl stops after some requests

I have a class that login to a coffee machine. I have a laravel app that "scan" all the coffee machines given in a range of IP address.
The problem is that Curl stops after 39, 128 or even 90 requests. So, I don't know what is the problem or if is a memory leak because PHP and Curl doesn't show any error.
I need advice or tips how to achieve this type of problem. Below is my code.
CoffeeMachine class
<?php
namespace Starbucks\CoffeeMachine;
class CoffeeMachine
{
private $url = '';
private $username = '';
private $password = '';
private $session;
private $response;
private $responses;
private $lastMessage = '';
private $lastStatus = FALSE;
private $authenticated = FALSE;
private function setFailStatus($message = '')
{
$this->lastStatus = FALSE;
$this->lastMessage = $message;
return FALSE;
}
private function setSuccessStatus($message = '')
{
$this->lastStatus = TRUE;
$this->lastMessage = $message;
return TRUE;
}
public function __construct($url = '', $username = 'admin', $password = 'admin')
{
$this->boot();
$this->url = $url;
$this->username = $username;
$this->password = $password;
$this->session = curl_init();
curl_setopt($this->session, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($this->session, CURLOPT_FAILONERROR, 1);
curl_setopt($this->session, CURLOPT_FORBID_REUSE, 1);
curl_setopt($this->session, CURLOPT_FRESH_CONNECT, 1);
}
public function getResponse()
{
return $this->response;
}
public function login()
{
curl_setopt($this->session, CURLOPT_URL, $this->url . '/cgi-bin/dologin');
curl_setopt($this->session, CURLOPT_POST, 1);
curl_setopt($this->session, CURLOPT_POSTFIELDS, array(
'username' => $this->username,
'password' => $this->password
)
);
curl_setopt($this->session, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->session, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($this->session, CURLOPT_HEADER, 0);
$response = curl_exec($this->session);
$response = json_decode($response, 1);
if (!isset($response['response'])) return $this->setFailStatus('Auth with no data...');
if ($response['response'] != 'success') return $this->setFailStatus('Access denied...');
$this->response = $response;
$this->lastStatus = TRUE;
$this->lastMessage = 'OK';
$this->authenticated = TRUE;
return TRUE;
}
public function getDeviceInfo()
{
}
public function logout()
{
curl_close($this->session);
}
}
Discover method in a range of IP
<?php
public function discover(Request $request)
{
$from = ip2long($request->input('from', '0.0.0.0'));
$to = ip2long($request->input('to', '255.255.255.255'));
$ips = array();
// CHUNK IN GROUPS OF 10 FOR WAIT 60 SECONDS, BUT NOT WORK
for($i = $from; $i < $to; $i++) $ips[] = long2ip($i);
$group_of_ips = array_chunk($ips, 10);
// TESTED THIS AND NOT WORK
$default_max_execution_time = ini_get('max_execution_time');
ini_set('max_execution_time', ((abs($from - $to) * 5) + (count($group_of_ips) * 60)) );
$machine_ips = array();
foreach($group_of_ips as $index => $row) {
foreach($row as $ip) {
$gs = new CoffeeMachine($ip, 'admin', 'admin');
if ($gs->login()) {
$machine_ips[] = $ip;
}
$gs->logout();
}
sleep(60); // TESTED THIS AND NOT WORK
}
ini_set('max_execution_time', $default_max_execution_time);
/* RETURN THE COFFEE MACHINE IP ADDRESS */
return $machine_ips;
}
add more error checking. some snippets from my curl wrapper, hhb_curl:
$this->curlh = curl_init ( '' ); // why empty string? PHP Fatal error: Uncaught TypeError: curl_init() expects parameter 1 to be string, null given
if (! $this->curlh) {
throw new RuntimeException ( 'curl_init failed!' );
}
here i verify that curl_init managed to create a curl resource, if it didn't, i throw a RuntimeException. you should do the same.
$ret = curl_exec ( $this->curlh );
if ($this->errno ()) {
throw new RuntimeException ( 'curl_exec failed. errno: ' . var_export ( $this->errno (), true ) . ' error: ' . var_export ( $this->error (), true ) );
}
here, i verify that curl_exec didn't register any errors, else i throw a RuntimeException. you should do the same. (it uses curl_errno($ch) )
function setopt_array(array $options): bool {
foreach ( $options as $option => $value ) {
$this->setopt ( $option, $value );
}
return true;
}
here i make sure my setopt_array doesn't actually use curl_setopt_array, but my own curl_setopt wrapper, you should do the same, for reasons explained below.
private function _setopt(int $option, $value): bool {
$ret = curl_setopt ( $this->curlh, $option, $value );
if (! $ret) {
throw new InvalidArgumentException ( 'curl_setopt failed. errno: ' . $this->errno () . '. error: ' . $this->error () . '. option: ' . var_export ( $this->_curlopt_name ( $option ), true ) . ' (' . var_export ( $option, true ) . '). value: ' . var_export ( $value, true ) );
}
$this->curloptions [$option] = $value;
return $ret; // true...
}
here i verify that curl_setopt succeeded, if it didn't, i throw an InvalidArgumentException, you should do the same (or at least throw some kind of exception, rather than the silent ignore your current code does.), and unlike curl_setopt_array, you can actually easily determine which option couldn't be set.
and when debugging curl code, always set CURLOPT_VERBOSE. (hhb_curl always does this, and gives curl a CURLOPT_STDERR tempfile() to put the verbose/error logs in, and gives you the logs through $hc->getStdErr() ), you should at least add some form of CURLOPT_VERBOSE support for debugging. my curl wrapper, hhb_curl, is available here https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php
Adding a timeout to the curl execution solves the problem. You need to monitor the response time for each device you want to reach. for me, 10 seconds for CONNECTTIMEOUT and TIMEOUT works fine.
<?php
namespace Starbucks\CoffeeMachine;
class CoffeeMachine
{
private $url = '';
private $username = '';
private $password = '';
private $session;
private $response;
private $responses;
private $lastMessage = '';
private $lastStatus = FALSE;
private $authenticated = FALSE;
private function setFailStatus($message = '')
{
$this->lastStatus = FALSE;
$this->lastMessage = $message;
return FALSE;
}
private function setSuccessStatus($message = '')
{
$this->lastStatus = TRUE;
$this->lastMessage = $message;
return TRUE;
}
public function __construct($url = '', $username = 'admin', $password = 'admin')
{
$this->boot();
$this->url = $url;
$this->username = $username;
$this->password = $password;
$this->session = curl_init();
curl_setopt($this->session, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($this->session, CURLOPT_TIMEOUT, 10);
curl_setopt($this->session, CURLOPT_FAILONERROR, 1);
curl_setopt($this->session, CURLOPT_FORBID_REUSE, 1);
curl_setopt($this->session, CURLOPT_FRESH_CONNECT, 1);
}
public function getResponse()
{
return $this->response;
}
public function login()
{
curl_setopt($this->session, CURLOPT_URL, $this->url . '/cgi-bin/dologin');
curl_setopt($this->session, CURLOPT_POST, 1);
curl_setopt($this->session, CURLOPT_POSTFIELDS, array(
'username' => $this->username,
'password' => $this->password
)
);
curl_setopt($this->session, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->session, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($this->session, CURLOPT_HEADER, 0);
$response = curl_exec($this->session);
if (curl_errno($this->session)) {
$msg = $this->url . "\n" . curl_errno($this->session) . "\n" . curl_error($this->session);
return $this->setFailStatus($msg);
}
$response = json_decode($response, 1);
if (!isset($response['response'])) return $this->setFailStatus('Auth with no data...');
if ($response['response'] != 'success') return $this->setFailStatus('Access denied...');
$this->response = $response;
$this->lastStatus = TRUE;
$this->lastMessage = 'OK';
$this->authenticated = TRUE;
return TRUE;
}
public function getDeviceInfo()
{
}
public function logout()
{
curl_close($this->session);
}
}
Now I can loop and reach CoffeeMachines =)

Object created using reflection and setValue has empty properties

I'm trying to generate an object of class Bar from POST data. I'm doing this using a function that I found here.
I post data from foo.php to bar.php.
bar.php successfully receives the post data and runs the static method Bar::generate, which returns a Bar object.
The problem is, even though the function receives the correct data and knows where to set it, the returned objects properties are empty.
foo.php
<?php
function postArray($array, $destScript){
try {
$ch = curl_init();
if (FALSE === $ch){
throw new Exception('failed to initialize');
}
curl_setopt($ch, CURLOPT_URL,$destScript);
curl_setopt($ch, CURLOPT_POST, count($array));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$content = curl_exec($ch);
return $content;
if (FALSE === $content)
throw new Exception(curl_error($ch), curl_errno($ch));
} catch(Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()),E_USER_ERROR);
}
}
echo postArray(array('action' => 'generate', 'first' => 'yes', 'second' => 'no', 'third' => 'maybe'), 'http://herbie.eu/indev/bar.php');
?>
bar.php
<?php
class Bar{
public $first;
public $second;
public $third;
private function __construct($options){
$this->loadFromArray($options);
}
private function loadFromArray($array) {
$class = new ReflectionClass(get_class($this));
$props = $class->getProperties();
foreach($props as $p) {
if (isset($array[$p->getName()])){
$p->setValue($this, $array[$p->getName]);
echo $p->getName()." = ".$array[$p->getName()]."<br>";
}
}
echo "<br>";
}
static public function generate($options){
try{
return new Bar($options);
}
catch(NotFoundException $unfe){
echo 'Bar::generate failed + '.$unfe;
return NULL;
}
}
}
if(!empty($_POST['action'])){
if($_POST['action'] == "generate"){
$booking = Bar::generate($_POST);
echo "success ".count($_POST)."<br>";
print_r($booking);
}
}
else{
echo "WARNING_L0: ${_POST}['action'] not set";
}
?>
Running foo.php returns,
first = yes
second = no
third = maybe
success 4
Bar Object ( [first] => [second] => [third] => )
As you can see, the ReflectionClass in loadFromArray knows exactly what to put where, but the returned object is empty. The 4 is the result of count($_POST).

PHP cURL Web Crawler

This code is running fine in terminal when I run the file as
$php webcrawler.php
However, I am curious on what I need to do to make it run on URLs specified in the console i.e.
$php webcrawler.php http://samplesite.com
Here is the full code I have so far:
class Ga_track
{
function get_ga_implemented($url)
{
$options = array(
CURLOPT_RETURNTRANSFER => TRUE, // return web page
CURLOPT_HEADER => TRUE, // don't return headers
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 6.1; WOW64)", // who am i
CURLOPT_SSL_VERIFYHOST => FALSE, //ssl verify host
CURLOPT_SSL_VERIFYPEER => FALSE, //ssl verify peer
CURLOPT_NOBODY => FALSE
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
//2> Grab content of the url using CURL
$content = curl_exec($ch);
$flag1_trackpage = false; //FLag for the phrase '_trackPageview'
$flag2_ga_js = false; //FLag for the phrase 'ga.js'
// Script Regex
$script_regex = "/<script\b[^>]*>([\s\S]*?)<\/script>/i";
// UA_ID Regex
$ua_regex = "/UA-[0-9]{5,}-[0-9]{1,}/";
preg_match_all($script_regex, $content, $inside_script);
for ($i = 0; $i < count($inside_script[0]); $i++)
{
if (stristr($inside_script[0][$i], "ga.js"))
$flag2_ga_js = TRUE;
if (stristr($inside_script[0][$i], "_trackPageview"))
$flag1_trackpage = TRUE;
}
preg_match_all($ua_regex, $content, $ua_id);
//6> Check whether all 3 word phrases are present or not.
if ($flag2_ga_js && $flag1_trackpage && count($ua_id > 0))
return ($ua_id);
else
return (NULL);
}
}
$ga_obj = new Ga_track();
$url = "http://www.samplesite.com";
$ua_id = $ga_obj->get_ga_implemented($url);
if ($ua_id == NULL)
{
echo "USING GA: NO\r\n";
}
else
{
echo "USING GA: YES\r\n";
}
So I was able to find a solution for using the URL in the command line. I have to use cli and pass in the args. I am still having some trouble with it reading the content, but that is a separate issue. Here is the updated code:
class track {
function __construct($arg1, $arg2, $arg3) {
if(!$this->isCli()) die("Please use php-cli!");
if (!function_exists('curl_init')) die("Please install cURL!");
$this->hp = $arg1;
$this->rlevel = $arg2;
$this->rmax = $arg3;
}
function isCli() {
return php_sapi_name()==="cli";
}
function getContent() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->hp);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
function checkGA($content) {
$flag_ga = false;
$script_regex = "/<script\b[^>]*>([\s\S]*?)<\/script>/i";
preg_match_all($script_regex, $content, $inside_script);
for ($i = 0; $i < count($inside_script[0]); $i++)
{
if (stristr($inside_script[0][$i], "ga.js"))
$flag_ga = TRUE;
else
return (NULL);
}
}
}
/*
*
* Echo Output
*
*/
$track_obj = new track();
$ga = $track_obj->checkGA($content);
if ($ga == NULL) {
echo "USING GA: NO\r\n";
}
else {
echo "USING GA: YES\r\n";
}

Call Sharepoint WebService with PHP SoapClient

I extended the PHP SoapClient to use it with NTLM Sharepoint Authentication:
class NTLMSoapClient extends SoapClient {
function __doRequest($request, $location, $action, $version) {
$headers = array(
'Method: POST',
'Connection: Keep-Alive',
'User-Agent: PHP-SOAP-CURL',
'Content-Type: text/xml; charset=utf-8',
'SOAPAction: "' . $action . '"',
);
$this->__last_request_headers = $headers;
$ch = curl_init($location);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_USERPWD, $this->user . ':' . $this->password);
$response = curl_exec($ch);
return $response;
}
function __getLastRequestHeaders() {
return implode("n", $this->__last_request_headers) . "n";
}
public final function __call($methodName, array $methodParams) {
/*
* Is soapClient set? This check may look double here but in later
* developments it might help to trace bugs better and it avoids calls
* on wrong classes if $soapClient got set to something not SoapClient.
*/
if (!$this->soapClient instanceof \SoapClient) {
// Is not set
throw new \Exception('Variable soapClient is not a SoapClient class, have: ' . gettype($this->soapClient), 0xFF);
}
// Is it a "SOAP callback"?
if (substr($methodName, 0, 2) == '__') {
// Is SoapClient's method
$returned = call_user_func_array(array($this->soapClient, $methodName), $methodParams);
} else {
// Call it
$returned = $this->soapClient->__call($methodName, $methodParams);
}
// Return any values
return $returned;
}
}
class SPNTLMSoapClient extends NTLMSoapClient {
protected $user = 'xxxxxx';
protected $password = 'xxxxxxx';
}
class NTLMStream {
private $path;
private $mode;
private $options;
private $opened_path;
private $buffer;
private $pos;
public function stream_open($path, $mode, $options, $opened_path) {
echo "[NTLMStream::stream_open] $path , mode=$mode n";
$this->path = $path;
$this->mode = $mode;
$this->options = $options;
$this->opened_path = $opened_path;
$this->createBuffer($path);
return true;
}
public function stream_close() {
echo "[NTLMStream::stream_close] n";
curl_close($this->ch);
}
public function stream_read($count) {
echo "[NTLMStream::stream_read] $count n";
if (strlen($this->buffer) == 0) {
return false;
}
$read = substr($this->buffer, $this->pos, $count);
$this->pos += $count;
return $read;
}
public function stream_write($data) {
echo "[NTLMStream::stream_write] n";
if (strlen($this->buffer) == 0) {
return false;
}
return true;
}
public function stream_eof() {
echo "[NTLMStream::stream_eof] ";
if ($this->pos > strlen($this->buffer)) {
echo "true n";
return true;
}
echo "false n";
return false;
}
/* return the position of the current read pointer */
public function stream_tell() {
echo "[NTLMStream::stream_tell] n";
return $this->pos;
}
public function stream_flush() {
echo "[NTLMStream::stream_flush] n";
$this->buffer = null;
$this->pos = null;
}
public function stream_stat() {
echo "[NTLMStream::stream_stat] n";
$this->createBuffer($this->path);
$stat = array(
'size' => strlen($this->buffer),
);
return $stat;
}
public function url_stat($path, $flags) {
echo "[NTLMStream::url_stat] n";
$this->createBuffer($path);
$stat = array(
'size' => strlen($this->buffer),
);
return $stat;
}
/* Create the buffer by requesting the url through cURL */
private function createBuffer($path) {
if ($this->buffer) {
return;
}
echo "[NTLMStream::createBuffer] create buffer from : $pathn";
$this->ch = curl_init($path);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($this->ch, CURLOPT_USERPWD, $this->user . ':' . $this->password);
echo $this->buffer = curl_exec($this->ch);
echo "[NTLMStream::createBuffer] buffer size : " . strlen($this->buffer) . "bytesn";
$this->pos = 0;
}
}
class SPNTLMStream extends NTLMStream {
protected $user = 'xxxxxxx';
protected $password = 'xxxxxxxx';
}
stream_wrapper_unregister('https');
stream_wrapper_register('https', 'SPNTLMStream') or die("Failed to register protocol");
$wsdl = "https://wxxxxxxxxx?WSDL";
$client = new SPNTLMSoapClient($wsdl);
I succesfully call: "print_r($client->__getFunctions())" and get the following:
Array
(
[0] => CopyIntoItemsLocalResponse CopyIntoItemsLocal(CopyIntoItemsLocal $parameters)
[1] => CopyIntoItemsResponse CopyIntoItems(CopyIntoItems $parameters)
[2] => GetItemResponse GetItem(GetItem $parameters)
[3] => CopyIntoItemsLocalResponse CopyIntoItemsLocal(CopyIntoItemsLocal $parameters)
[4] => CopyIntoItemsResponse CopyIntoItems(CopyIntoItems $parameters)
[5] => GetItemResponse GetItem(GetItem $parameters)
)
My Question now is: How do I call these Methods with $client and parameters,
$client->__call('CopyIntoItems', $params) doesnt work
$client->CopyIntoItems($params) doesnt work
I never get any Response.....
Thx in advance....

Has anyone worked with this Highrise API PHP Wrapper library? I need help authenticating

So I downloaded a wrapper class from this github link:
https://github.com/ignaciovazquez/Highrise-PHP-Api
and I'm just trying to get any response whatsoever. So far, I can't even authenticate with my credentials so I was wondering if any who has used the API could help me.
I tried running one of the test files on Terminal with no arguments and this is what it told me:
Usage: php users.test.php [account-name] [access-token]
Alright, so then decided to get my credentials. So this is what I understand, and, please, correct if I'm wrong:
the account-name is that part that goes in the url to your highrise account. So if your url is:
https://exampleaccount.highrisehq.com/
then your account name is: "exampleaccount"
and your access token is your authentication token that you can find by going clicking on My info > API token inside your Highrise account.
Is that right?
Well anyways, I enter this info and script terminates with a fatal error and this message:
Fatal error: Uncaught exception 'Exception' with message 'API for User returned Status Code: 0 Expected Code: 200' in /Users/me/Sites/sandbox/PHP/highrise_api_class/lib/HighriseAPI.class.php:137
Stack trace:
#0 /Users/me/Sites/sandbox/PHP/highrise_api_class/lib/HighriseAPI.class.php(166): HighriseAPI->checkForErrors('User')
#1 /Users/me/Sites/sandbox/PHP/highrise_api_class/test/users.test.php(13): HighriseAPI->findMe()
#2 {main}
thrown in /Users/me/Sites/sandbox/PHP/highrise_api_class/lib/HighriseAPI.class.php on line 137
I'm complete n00b and I don't really understand what it's saying so I was wondering if any could help. It would be greatly appreciated.
The source of the test script (users.test.php) is:
<?php
require_once("../lib/HighriseAPI.class.php");
if (count($argv) != 3)
die("Usage: php users.test.php [account-name] [access-token]\n");
$hr = new HighriseAPI();
$hr->debug = false;
$hr->setAccount($argv[1]);
$hr->setToken($argv[2]);
print "Finding my user...\n";
$user = $hr->findMe();
print_r($user);
print "Finding all users...\n";
$users = $hr->findAllUsers();
print_r($users);
?>
and the source to the Highrise API wrapper file (Highrise.API.class) is:
<?php
/*
* http://developer.37signals.com/highrise/people
*
* TODO LIST:
* Add Tasks support
* Get comments for Notes / Emails
* findPeopleByTagName
* Get Company Name, etc proxy
* Convenience methods for saving Notes $person->saveNotes() to check if notes were modified, etc.
* Add Tags to Person
*/
class HighriseAPI
{
public $account;
public $token;
protected $curl;
public $debug;
public function __construct()
{
$this->curl = curl_init();
curl_setopt($this->curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Accept: application/xml', 'Content-Type: application/xml'));
// curl_setopt($curl,CURLOPT_POST,true);
curl_setopt($this->curl,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($this->curl,CURLOPT_SSL_VERIFYHOST,0);
}
public function setAccount($account)
{
$this->account = $account;
}
public function setToken($token)
{
$this->token = $token;
curl_setopt($this->curl,CURLOPT_USERPWD,$this->token.':x');
}
protected function postDataWithVerb($path, $request_body, $verb = "POST")
{
$this->curl = curl_init();
$url = "https://" . $this->account . ".highrisehq.com" . $path;
if ($this->debug)
print "postDataWithVerb $verb $url ============================\n";
curl_setopt($this->curl, CURLOPT_URL,$url);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $request_body);
if ($this->debug == true)
curl_setopt($this->curl, CURLOPT_VERBOSE, true);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Accept: application/xml', 'Content-Type: application/xml'));
curl_setopt($this->curl, CURLOPT_USERPWD,$this->token.':x');
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER,true);
if ($verb != "POST")
curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $verb);
else
curl_setopt($this->curl, CURLOPT_POST, true);
$ret = curl_exec($this->curl);
if ($this->debug == true)
print "Begin Request Body ============================\n" . $request_body . "End Request Body ==============================\n";
curl_setopt($this->curl,CURLOPT_HTTPGET, true);
return $ret;
}
protected function getURL($path)
{
curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Accept: application/xml', 'Content-Type: application/xml'));
curl_setopt($this->curl, CURLOPT_USERPWD,$this->token.':x');
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER,true);
$url = "https://" . $this->account . ".highrisehq.com" . $path;
if ($this->debug == true)
curl_setopt($this->curl, CURLOPT_VERBOSE, true);
curl_setopt($this->curl,CURLOPT_URL,$url);
$response = curl_exec($this->curl);
if ($this->debug == true)
print "Response: =============\n" . $response . "============\n";
return $response;
}
protected function getLastReturnStatus()
{
return curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
}
protected function getXMLObjectForUrl($url)
{
$xml = $this->getURL($url);
$xml_object = simplexml_load_string($xml);
return $xml_object;
}
protected function checkForErrors($type, $expected_status_codes = 200)
{
if (!is_array($expected_status_codes))
$expected_status_codes = array($expected_status_codes);
if (!in_array($this->getLastReturnStatus(), $expected_status_codes))
{
switch($this->getLastReturnStatus())
{
case 404:
throw new Exception("$type not found");
break;
case 403:
throw new Exception("Access denied to $type resource");
break;
case 507:
throw new Exception("Cannot create $type: Insufficient storage in your Highrise Account");
break;
default:
throw new Exception("API for $type returned Status Code: " . $this->getLastReturnStatus() . " Expected Code: " . implode(",", $expected_status_codes));
break;
}
}
}
/* Users */
public function findAllUsers()
{
$xml = $this->getUrl("/users.xml");
$this->checkForErrors("User");
$xml_object = simplexml_load_string($xml);
$ret = array();
foreach($xml_object->user as $xml_user)
{
$user = new HighriseUser();
$user->loadFromXMLObject($xml_user);
$ret[] = $user;
}
return $ret;
}
public function findMe()
{
$xml = $this->getUrl("/me.xml");
$this->checkForErrors("User");
$xml_obj = simplexml_load_string($xml);
$user = new HighriseUser();
$user->loadFromXMLObject($xml_obj);
return $user;
}
/* Tasks */
public function findCompletedTasks()
{
$xml = $this->getUrl("/tasks/completed.xml");
$this->checkForErrors("Tasks");
return $this->parseTasks($xml);
}
public function findAssignedTasks()
{
$xml = $this->getUrl("/tasks/assigned.xml");
$this->checkForErrors("Tasks");
return $this->parseTasks($xml);
}
public function findUpcomingTasks()
{
$xml = $this->getUrl("/tasks/upcoming.xml");
$this->checkForErrors("Tasks");
return $this->parseTasks($xml);
}
private function parseTasks($xml)
{
$xml_object = simplexml_load_string($xml);
$ret = array();
foreach($xml_object->task as $xml_task)
{
$task = new HighriseTask($this);
$task->loadFromXMLObject($xml_task);
$ret[] = $task;
}
return $ret;
}
public function findTaskById($id)
{
$xml = $this->getURL("/tasks/$id.xml");
$this->checkForErrors("Task");
$task_xml = simplexml_load_string($xml);
$task = new HighriseTask($this);
$task->loadFromXMLObject($task_xml);
return $task;
}
/* Notes & Emails */
public function findEmailById($id)
{
$xml = $this->getURL("/emails/$id.xml");
$this->checkForErrors("Email");
$email_xml = simplexml_load_string($xml);
$email = new HighriseEmail($this);
$email->loadFromXMLObject($email_xml);
return $email;
}
public function findNoteById($id)
{
$xml = $this->getURL("/notes/$id.xml");
$this->checkForErrors("Note");
$note_xml = simplexml_load_string($xml);
$note = new HighriseNote($this);
$note->loadFromXMLObject($note_xml);
return $note;
}
public function findPersonById($id)
{
$xml = $this->getURL("/people/$id.xml");
$this->checkForErrors("Person");
$xml_object = simplexml_load_string($xml);
$person = new HighrisePerson($this);
$person->loadFromXMLObject($xml_object);
return $person;
}
public function findAllTags()
{
$xml = $this->getUrl("/tags.xml");
$this->checkForErrors("Tags");
$xml_object = simplexml_load_string($xml);
$ret = array();
foreach($xml_object->tag as $tag)
{
$ret[(string)$tag->name] = new HighriseTag((string)$tag->id, (string)$tag->name);
}
return $ret;
}
public function findAllPeople()
{
return $this->parsePeopleListing("/people.xml");
}
public function findPeopleByTagName($tag_name)
{
$tags = $this->findAllTags();
foreach($tags as $tag)
{
if ($tag->name == $tag_name)
$tag_id = $tag->id;
}
if (!isset($tag_id))
throw new Excepcion("Tag $tag_name not found");
return $this->findPeopleByTagId($tag_id);
}
public function findPeopleByTagId($tag_id)
{
$url = "/people.xml?tag_id=" . $tag_id;
$people = $this->parsePeopleListing($url);
return $people;
}
public function findPeopleByEmail($email)
{
return $this->findPeopleBySearchCriteria(array("email"=>$email));
}
public function findPeopleByTitle($title)
{
$url = "/people.xml?title=" . urlencode($title);
$people = $this->parsePeopleListing($url);
return $people;
}
public function findPeopleByCompanyId($company_id)
{
$url = "/companies/" . urlencode($company_id) . "/people.xml";
$people = $this->parsePeopleListing($url);
return $people;
}
public function findPeopleBySearchTerm($search_term)
{
$url = "/people/search.xml?term=" . urlencode($search_term);
$people = $this->parsePeopleListing($url, 25);
return $people;
}
public function findPeopleBySearchCriteria($search_criteria)
{
$url = "/people/search.xml";
$sep = "?";
foreach($search_criteria as $criteria=>$value)
{
$url .= $sep . "criteria[" . urlencode($criteria) . "]=" . urlencode($value);
$sep = "&";
}
$people = $this->parsePeopleListing($url, 25);
return $people;
}
public function findPeopleSinceTime($time)
{
$url = "/people/search.xml?since=" . urlencode($time);
$people = $this->parsePeopleListing($url);
return $people;
}
public function parsePeopleListing($url, $paging_results = 500)
{
if (strstr($url, "?"))
$sep = "&";
else
$sep = "?";
$offset = 0;
$return = array();
while(true) // pagination
{
$xml_url = $url . $sep . "n=$offset";
// print $xml_url;
$xml = $this->getUrl($xml_url);
$this->checkForErrors("People");
$xml_object = simplexml_load_string($xml);
foreach($xml_object->person as $xml_person)
{
// print_r($xml_person);
$person = new HighrisePerson($this);
$person->loadFromXMLObject($xml_person);
$return[] = $person;
}
if (count($xml_object) != $paging_results)
break;
$offset += $paging_results;
}
return $return;
}
}
Sorry it's such a long file but if it helps, then so be it.
EDIT: So I guess I got it to work. I should've said that I was trying to test this library out on my local server and for some reason it would keep failing but when I moved the script to my development server on Rackspace cloud then it would work. This just puzzles me. Both servers have support for PHP curl so I can't really understand where the problem is.
EDIT: I'm not sure what the difference between the two server configurations could be but anyways here's a couple of screenshots from my phpinfo function output from both servers of my curl configuration:
Localhost server:
and the rackspace cloud server:
The fork of the API at...
https://github.com/AppSaloon/Highrise-PHP-Api
...seems more developed and better maintained.
Not so much as to provide an answer, but more a better starting point.
Ah, since there is really no HTTP error code 0 I expect that your request isn't being made to Highrise's website, or you are not correctly passing in the account name and token to the class. Can you include the source of your users.test.php class?
EDIT: tested the class and your code, and it works for me. You probably either copied the library file wrong or have your token copied wrong.
I had the same issue. I definitely had the wrong account. I had https://foo.highrisehq.com instead of just foo.

Categories