<?php | <?php |
/** | /** |
* Databaase class. | * Databaase class. |
*/ | */ |
class SetteeDatabase { | class SetteeDatabase { |
/** | /** |
* Base URL of the CouchDB REST API | * Base URL of the CouchDB REST API |
*/ | */ |
private $conn_url; | private $conn_url; |
/** | /** |
* HTTP REST Client instance | * HTTP REST Client instance |
*/ | */ |
protected $rest_client; | protected $rest_client; |
/** | /** |
* Name of the database | * Name of the database |
*/ | */ |
private $dbname; | private $dbname; |
/** | /** |
* Default constructor | * Default constructor |
*/ | */ |
function __construct($conn_url, $dbname) { | function __construct($conn_url, $dbname) { |
$this->conn_url = $conn_url; | $this->conn_url = $conn_url; |
$this->dbname = $dbname; | $this->dbname = $dbname; |
$this->rest_client = SetteeRestClient::get_instance($this->conn_url); | $this->rest_client = SetteeRestClient::get_instance($this->conn_url); |
} | } |
/** | /** |
* Get UUID from CouchDB | * Get UUID from CouchDB |
* | * |
* @return | * @return |
* CouchDB-generated UUID string | * CouchDB-generated UUID string |
* | * |
*/ | */ |
function gen_uuid() { | function gen_uuid() { |
$ret = $this->rest_client->http_get('_uuids'); | $ret = $this->rest_client->http_get('_uuids'); |
return $ret['decoded']->uuids[0]; // should never be empty at this point, so no checking | return $ret['decoded']->uuids[0]; // should never be empty at this point, so no checking |
} | } |
/** | /** |
* Create or update a document database | * Create or update a document database |
* | * |
* @param $document | * @param $document |
* PHP object, a PHP associative array, or a JSON String representing the document to be saved. PHP Objects and arrays are JSON-encoded automatically. | * PHP object, a PHP associative array, or a JSON String representing the document to be saved. PHP Objects and arrays are JSON-encoded automatically. |
* | * |
* <p>If $document has a an "_id" property set, it will be used as document's unique id (even for "create" operation). | * <p>If $document has a an "_id" property set, it will be used as document's unique id (even for "create" operation). |
* If "_id" is missing, CouchDB will be used to generate a UUID. | * If "_id" is missing, CouchDB will be used to generate a UUID. |
* | * |
* <p>If $document has a "_rev" property (revision), document will be updated, rather than creating a new document. | * <p>If $document has a "_rev" property (revision), document will be updated, rather than creating a new document. |
* You have to provide "_rev" if you want to update an existing document, otherwise operation will be assumed to be | * You have to provide "_rev" if you want to update an existing document, otherwise operation will be assumed to be |
* one of creation and you will get a duplicate document exception from CouchDB. Also, you may not provide "_rev" but | * one of creation and you will get a duplicate document exception from CouchDB. Also, you may not provide "_rev" but |
* not provide "_id" since that is an invalid input. | * not provide "_id" since that is an invalid input. |
* | * |
* @param $allowRevAutoDetection | * @param $allowRevAutoDetection |
* Default: false. When true and _rev is missing from the document, save() function will auto-detect latest revision | * Default: false. When true and _rev is missing from the document, save() function will auto-detect latest revision |
* for a document and use it. This option is "false" by default because it involves an extra http HEAD request and | * for a document and use it. This option is "false" by default because it involves an extra http HEAD request and |
* therefore can make save() operation slightly slower if such auto-detection is not required. | * therefore can make save() operation slightly slower if such auto-detection is not required. |
* | * |
* @return | * @return |
* document object with the database id (uuid) and revision attached; | * document object with the database id (uuid) and revision attached; |
* | * |
* @throws SetteeCreateDatabaseException | * @throws SetteeCreateDatabaseException |
*/ | */ |
function save($document, $allowRevAutoDetection = false) { | function save($document, $allowRevAutoDetection = false) { |
if (is_string($document)) { | if (is_string($document)) { |
$document = json_decode($document); | $document = json_decode($document); |
} | } |
// Allow passing of $document as an array (for syntactic simplicity and also because in JSON world it does not matter) | // Allow passing of $document as an array (for syntactic simplicity and also because in JSON world it does not matter) |
if (is_array($document)) { | if (is_array($document)) { |
$document = (object) $document; | $document = (object) $document; |
} | } |
if (empty($document->_id) && empty($document->_rev)) { | if (empty($document->_id) && empty($document->_rev)) { |
$id = $this->gen_uuid(); | $id = $this->gen_uuid(); |
} elseif (empty($document->_id) && !empty($document->_rev)) { | } elseif (empty($document->_id) && !empty($document->_rev)) { |
throw new SetteeWrongInputException("Error: You can not save a document with a revision provided, but missing id"); | throw new SetteeWrongInputException("Error: You can not save a document with a revision provided, but missing id"); |
} else { | } else { |
$id = $document->_id; | $id = $document->_id; |
if ($allowRevAutoDetection) { | if ($allowRevAutoDetection) { |
try { | try { |
$rev = $this->get_rev($id); | $rev = $this->get_rev($id); |
} catch (SetteeRestClientException $e) { | } catch (SetteeRestClientException $e) { |
// auto-detection may fail legitimately, if a document has never been saved before (new doc), so skipping error | // auto-detection may fail legitimately, if a document has never been saved before (new doc), so skipping error |
} | } |
if (!empty($rev)) { | if (!empty($rev)) { |
$document->_rev = $rev; | $document->_rev = $rev; |
} | } |
} | } |
} | } |
$full_uri = $this->dbname . "/" . $this->safe_urlencode($id); | $full_uri = $this->dbname . "/" . $this->safe_urlencode($id); |
$document_json = json_encode($document, JSON_NUMERIC_CHECK); | $document_json = json_encode($document, JSON_NUMERIC_CHECK); |
$ret = $this->rest_client->http_put($full_uri, $document_json); | $ret = $this->rest_client->http_put($full_uri, $document_json); |
$document->_id = $ret['decoded']->id; | $document->_id = $ret['decoded']->id; |
$document->_rev = $ret['decoded']->rev; | $document->_rev = $ret['decoded']->rev; |
return $document; | return $document; |
} | } |
/** | /** |
* @param $doc | * @param $doc |
* @param $name | * @param $name |
* @param $content | * @param $content |
* Content of the attachment in a string-buffer format. This function will automatically base64-encode content for | * Content of the attachment in a string-buffer format. This function will automatically base64-encode content for |
* you, so you don't have to do it. | * you, so you don't have to do it. |
* @param $mime_type | * @param $mime_type |
* Optional. Will be auto-detected if not provided | * Optional. Will be auto-detected if not provided |
* @return void | * @return void |
*/ | */ |
public function add_attachment($doc, $name, $content, $mime_type = null) { | public function add_attachment($doc, $name, $content, $mime_type = null) { |
if (empty($doc->_attachments) || !is_object($doc->_attachments)) { | if (empty($doc->_attachments) || !is_object($doc->_attachments)) { |
$doc->_attachments = new stdClass(); | $doc->_attachments = new stdClass(); |
} | } |
if (empty($mime_type)) { | if (empty($mime_type)) { |
$mime_type = $this->rest_client->content_mime_type($content); | $mime_type = $this->rest_client->content_mime_type($content); |
} | } |
$doc->_attachments->$name = new stdClass(); | $doc->_attachments->$name = new stdClass(); |
$doc->_attachments->$name->content_type = $mime_type; | $doc->_attachments->$name->content_type = $mime_type; |
$doc->_attachments->$name->data = base64_encode($content); | $doc->_attachments->$name->data = base64_encode($content); |
} | } |
/** | /** |
* @param $doc | * @param $doc |
* @param $name | * @param $name |
* @param $file | * @param $file |
* Full path to a file (e.g. as returned by PHP's realpath function). | * Full path to a file (e.g. as returned by PHP's realpath function). |
* @param $mime_type | * @param $mime_type |
* Optional. Will be auto-detected if not provided | * Optional. Will be auto-detected if not provided |
* @return void | * @return void |
*/ | */ |
public function add_attachment_file($doc, $name, $file, $mime_type = null) { | public function add_attachment_file($doc, $name, $file, $mime_type = null) { |
$content = file_get_contents($file); | $content = file_get_contents($file); |
$this->add_attachment($doc, $name, $content, $mime_type); | $this->add_attachment($doc, $name, $content, $mime_type); |
} | } |
/** | /** |
* | * |
* Retrieve a document from CouchDB | * Retrieve a document from CouchDB |
* | * |
* @throws SetteeWrongInputException | * @throws SetteeWrongInputException |
* | * |
* @param $id | * @param $id |
* Unique ID (usually: UUID) of the document to be retrieved. | * Unique ID (usually: UUID) of the document to be retrieved. |
* @return | * @return |
* database document in PHP object format. | * database document in PHP object format. |
*/ | */ |
function get($id) { | function get($id) { |
if (empty($id)) { | if (empty($id)) { |
throw new SetteeWrongInputException("Error: Can't retrieve a document without a uuid."); | throw new SetteeWrongInputException("Error: Can't retrieve a document without a uuid."); |
} | } |
$full_uri = $this->dbname . "/" . $this->safe_urlencode($id); | $full_uri = $this->dbname . "/" . $this->safe_urlencode($id); |
$full_uri = str_replace("%3Frev%3D", "?rev=", $full_uri); | $full_uri = str_replace("%3Frev%3D", "?rev=", $full_uri); |
$ret = $this->rest_client->http_get($full_uri); | $ret = $this->rest_client->http_get($full_uri); |
return $ret['decoded']; | return $ret['decoded']; |
} | } |
/** | /** |
* | * |
* Get the latest revision of a document with document id: $id in CouchDB. | * Get the latest revision of a document with document id: $id in CouchDB. |
* | * |
* @throws SetteeWrongInputException | * @throws SetteeWrongInputException |
* | * |
* @param $id | * @param $id |
* Unique ID (usually: UUID) of the document to be retrieved. | * Unique ID (usually: UUID) of the document to be retrieved. |
* @return | * @return |
* database document in PHP object format. | * database document in PHP object format. |
*/ | */ |
function get_rev($id) { | function get_rev($id) { |
if (empty($id)) { | if (empty($id)) { |
throw new SetteeWrongInputException("Error: Can't query a document without a uuid."); | throw new SetteeWrongInputException("Error: Can't query a document without a uuid."); |
} | } |
$full_uri = $this->dbname . "/" . $this->safe_urlencode($id); | $full_uri = $this->dbname . "/" . $this->safe_urlencode($id); |
$headers = $this->rest_client->http_head($full_uri); | $headers = $this->rest_client->http_head($full_uri); |
if (empty($headers['Etag'])) { | if (empty($headers['Etag'])) { |
throw new SetteeRestClientException("Error: could not retrieve revision. Server unexpectedly returned empty Etag"); | throw new SetteeRestClientException("Error: could not retrieve revision. Server unexpectedly returned empty Etag"); |
} | } |
$etag = str_replace('"', '', $headers['Etag']); | $etag = str_replace('"', '', $headers['Etag']); |
return $etag; | return $etag; |
} | } |
/** | /** |
* Delete a document | * Delete a document |
* | * |
* @param $document | * @param $document |
* a PHP object or JSON representation of the document that has _id and _rev fields. | * a PHP object or JSON representation of the document that has _id and _rev fields. |
* | * |
* @return void | * @return void |
*/ | */ |
function delete($document) { | function delete($document) { |
if (!is_object($document)) { | if (!is_object($document)) { |
$document = json_decode($document); | $document = json_decode($document); |
} | } |
$full_uri = $this->dbname . "/" . $this->safe_urlencode($document->_id) . "?rev=" . $document->_rev; | $full_uri = $this->dbname . "/" . $this->safe_urlencode($document->_id) . "?rev=" . $document->_rev; |
$this->rest_client->http_delete($full_uri); | $this->rest_client->http_delete($full_uri); |
} | } |
/* ----------------- View-related functions -------------- */ | /* ----------------- View-related functions -------------- */ |
/** | /** |
* Create a new view or update an existing one. | * Create a new view or update an existing one. |
* | * |
* @param $design_doc | * @param $design_doc |
* @param $view_name | * @param $view_name |
* @param $map_src | * @param $map_src |
* Source code of the map function in Javascript | * Source code of the map function in Javascript |
* @param $reduce_src | * @param $reduce_src |
* Source code of the reduce function in Javascript (optional) | * Source code of the reduce function in Javascript (optional) |
* @return void | * @return void |
*/ | */ |
function save_view($design_doc, $view_name, $map_src, $reduce_src = null) { | function save_view($design_doc, $view_name, $map_src, $reduce_src = null) { |
$obj = new stdClass(); | $obj = new stdClass(); |
$obj->_id = "_design/" . urlencode($design_doc); | $obj->_id = "_design/" . urlencode($design_doc); |
$view_name = urlencode($view_name); | $view_name = urlencode($view_name); |
$obj->views->$view_name->map = $map_src; | $obj->views->$view_name->map = $map_src; |
if (!empty($reduce_src)) { | if (!empty($reduce_src)) { |
$obj->views->$view_name->reduce = $reduce_src; | $obj->views->$view_name->reduce = $reduce_src; |
} | } |
// allow safe updates (even if slightly slower due to extra: rev-detection check). | // allow safe updates (even if slightly slower due to extra: rev-detection check). |
return $this->save($obj, true); | return $this->save($obj, true); |
} | } |
/** | /** |
* Create a new view or update an existing one. | * Create a new view or update an existing one. |
* | * |
* @param $design_doc | * @param $design_doc |
* @param $view_name | * @param $view_name |
* @param $key | * @param $key |
* key parameter to a view. Can be a single value or an array (for a range). If passed an array, function assumes | * key parameter to a view. Can be a single value or an array (for a range). If passed an array, function assumes |
* that first element is startkey, second: endkey. | * that first element is startkey, second: endkey. |
* @param $descending | * @param $descending |
* return results in descending order. Please don't forget that if you are using a startkey/endkey, when you change | * return results in descending order. Please don't forget that if you are using a startkey/endkey, when you change |
* order you also need to swap startkey and endkey values! | * order you also need to swap startkey and endkey values! |
* | * |
* @return void | * @return void |
*/ | */ |
function get_view($design_doc, $view_name, $key = null, $descending = false, $limit = false, $reduce = null, $startdocid = null) { | function get_view($design_doc, $view_name, $key = null, $descending = false, $limit = false, $reduce = null, $startdocid = null) { |
$id = "_design/" . urlencode($design_doc); | $id = "_design/" . urlencode($design_doc); |
$view_name = urlencode($view_name); | $view_name = urlencode($view_name); |
$id .= "/_view/$view_name"; | $id .= "/_view/$view_name"; |
$data = array(); | $data = array(); |
if (!empty($key)) { | if (!empty($key)) { |
if (is_string($key)) { | if (is_string($key)) { |
$data = "key=" . '"' . $key . '"'; | $data = "key=" . '"' . $key . '"'; |
} elseif (is_array($key)) { | } elseif (is_array($key)) { |
list($startkey, $endkey) = $key; | list($startkey, $endkey) = $key; |
$data = "startkey=" . '"' . $startkey . '"&' . "endkey=" . '"' . $endkey . '"'; | $data = "startkey=" . '"' . $startkey . '"&' . "endkey=" . '"' . $endkey . '"'; |
} | } |
if ($descending) { | if ($descending) { |
$data .= "&descending=true"; | $data .= "&descending=true"; |
} | } |
if ($startdocid != null) { | if ($startdocid != null) { |
$data .= "&startkey_docid='$startdocid'"; | $data .= "&startkey_docid='$startdocid'"; |
} | } |
if ($reduce != null) { | if ($reduce === true) { |
if ($reduce == true) { | |
$data .= "&reduce=true"; | $data .= "&reduce=true"; |
} else { | } else if ($reduce === false){ |
$data .= "&reduce=false"; | $data .= "&reduce=false"; |
} | |
} | } |
if ($limit) { | if ($limit) { |
$data .= "&limit=" . $limit; | $data .= "&limit=" . $limit; |
} | } |
} | } |
if (empty($id)) { | if (empty($id)) { |
throw new SetteeWrongInputException("Error: Can't retrieve a document without a uuid."); | throw new SetteeWrongInputException("Error: Can't retrieve a document without a uuid."); |
} | } |
$full_uri = $this->dbname . "/" . $this->safe_urlencode($id); | $full_uri = $this->dbname . "/" . $this->safe_urlencode($id); |
$full_uri = str_replace("%253Fgroup%253D", "?group=", $full_uri); | $full_uri = str_replace("%253Fgroup%253D", "?group=", $full_uri); |
$full_uri = str_replace("%253Flimit%253D", "?limit=", $full_uri); | $full_uri = str_replace("%253Flimit%253D", "?limit=", $full_uri); |
$ret = $this->rest_client->http_get($full_uri, $data); | $ret = $this->rest_client->http_get($full_uri, $data); |
//$ret['decoded'] = str_replace("?k","&k",$ret['decoded']); | //$ret['decoded'] = str_replace("?k","&k",$ret['decoded']); |
return $ret['decoded']; | return $ret['decoded']; |
} | } |
/** | /** |
* @param $id | * @param $id |
* @return | * @return |
* return a properly url-encoded id. | * return a properly url-encoded id. |
*/ | */ |
private function safe_urlencode($id) { | private function safe_urlencode($id) { |
//-- System views like _design can have "/" in their URLs. | //-- System views like _design can have "/" in their URLs. |
$id = rawurlencode($id); | $id = rawurlencode($id); |
if (substr($id, 0, 1) == '_') { | if (substr($id, 0, 1) == '_') { |
$id = str_replace('%2F', '/', $id); | $id = str_replace('%2F', '/', $id); |
} | } |
return $id; | return $id; |
} | } |
/** Getter for a database name */ | /** Getter for a database name */ |
function get_name() { | function get_name() { |
return $this->dbname; | return $this->dbname; |
} | } |
} | } |
<?php | <?php |
/** | /** |
* HTTP REST Client for CouchDB API | * HTTP REST Client for CouchDB API |
*/ | */ |
class SetteeRestClient { | class SetteeRestClient { |
/** | /** |
* HTTP Timeout in Milliseconds | * HTTP Timeout in Milliseconds |
*/ | */ |
const HTTP_TIMEOUT = 2000; | const HTTP_TIMEOUT = 2000; |
private $base_url; | private $base_url; |
private $curl; | private $curl; |
private static $curl_workers = array(); | private static $curl_workers = array(); |
/** | /** |
* Singleton factory method | * Singleton factory method |
*/ | */ |
static function get_instance($base_url) { | static function get_instance($base_url) { |
if (empty(self::$curl_workers[$base_url])) { | if (empty(self::$curl_workers[$base_url])) { |
self::$curl_workers[$base_url] = new SetteeRestClient($base_url); | self::$curl_workers[$base_url] = new SetteeRestClient($base_url); |
} | } |
return self::$curl_workers[$base_url]; | return self::$curl_workers[$base_url]; |
} | } |
/** | /** |
* Class constructor | * Class constructor |
*/ | */ |
private function __construct($base_url) { | private function __construct($base_url) { |
$this->base_url = $base_url; | $this->base_url = $base_url; |
$curl = curl_init(); | $curl = curl_init(); |
curl_setopt($curl, CURLOPT_USERAGENT, "Settee CouchDB Client/1.0"); | curl_setopt($curl, CURLOPT_USERAGENT, "Settee CouchDB Client/1.0"); |
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); | curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); |
curl_setopt($curl, CURLOPT_HEADER, 0); | curl_setopt($curl, CURLOPT_HEADER, 0); |
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); | curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); |
curl_setopt($curl, CURLOPT_TIMEOUT_MS, self::HTTP_TIMEOUT); | curl_setopt($curl, CURLOPT_TIMEOUT_MS, self::HTTP_TIMEOUT); |
curl_setopt($curl, CURLOPT_FORBID_REUSE, false); // Connection-pool for CURL | curl_setopt($curl, CURLOPT_FORBID_REUSE, false); // Connection-pool for CURL |
$this->curl = $curl; | $this->curl = $curl; |
} | } |
/** | /** |
* Class destructor cleans up any resources | * Class destructor cleans up any resources |
*/ | */ |
function __destruct() { | function __destruct() { |
curl_close($this->curl); | curl_close($this->curl); |
} | } |
/** | /** |
* HTTP HEAD | * HTTP HEAD |
* | * |
* @return | * @return |
* Raw HTTP Headers of the response. | * Raw HTTP Headers of the response. |
* | * |
* @see: http://www.php.net/manual/en/context.params.php | * @see: http://www.php.net/manual/en/context.params.php |
* | * |
*/ | */ |
function http_head($uri) { | function http_head($uri) { |
curl_setopt($this->curl, CURLOPT_HEADER, 1); | curl_setopt($this->curl, CURLOPT_HEADER, 1); |
$full_url = $this->get_full_url($uri); | $full_url = $this->get_full_url($uri); |
curl_setopt($this->curl, CURLOPT_URL, $full_url); | curl_setopt($this->curl, CURLOPT_URL, $full_url); |
curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); | curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); |
curl_setopt($this->curl, CURLOPT_NOBODY, true); | curl_setopt($this->curl, CURLOPT_NOBODY, true); |
$response = curl_exec($this->curl); | $response = curl_exec($this->curl); |
// Restore default values | // Restore default values |
curl_setopt($this->curl, CURLOPT_NOBODY, false); | curl_setopt($this->curl, CURLOPT_NOBODY, false); |
curl_setopt($this->curl, CURLOPT_HEADER, false); | curl_setopt($this->curl, CURLOPT_HEADER, false); |
$resp_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); | $resp_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); |
if ($resp_code == 404 ) { | if ($resp_code == 404 ) { |
throw new SetteeRestClientException("Couch document not found at: '$full_url'"); | throw new SetteeRestClientException("Couch document not found at: '$full_url'"); |
} | } |
if (function_exists('http_parse_headers')) { | if (function_exists('http_parse_headers')) { |
$headers = http_parse_headers($response); | $headers = http_parse_headers($response); |
} | } |
else { | else { |
$headers = $this->_http_parse_headers($response); | $headers = $this->_http_parse_headers($response); |
} | } |
return $headers; | return $headers; |
} | } |
/** | /** |
* Backup PHP impl. for when PECL http_parse_headers() function is not available | * Backup PHP impl. for when PECL http_parse_headers() function is not available |
* | * |
* @param $header | * @param $header |
* @return array | * @return array |
* @source http://www.php.net/manual/en/function.http-parse-headers.php#77241 | * @source http://www.php.net/manual/en/function.http-parse-headers.php#77241 |
*/ | */ |
private function _http_parse_headers( $header ) { | private function _http_parse_headers( $header ) { |
$retVal = array(); | $retVal = array(); |
$fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header)); | $fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header)); |
foreach( $fields as $field ) { | foreach( $fields as $field ) { |
if( preg_match('/([^:]+): (.+)/m', $field, $match) ) { | if( preg_match('/([^:]+): (.+)/m', $field, $match) ) { |
$match[1] = preg_replace('/(?<=^|[\x09\x20\x2D])./e', 'strtoupper("\0")', strtolower(trim($match[1]))); | $match[1] = preg_replace('/(?<=^|[\x09\x20\x2D])./e', 'strtoupper("\0")', strtolower(trim($match[1]))); |
if( isset($retVal[$match[1]]) ) { | if( isset($retVal[$match[1]]) ) { |
$retVal[$match[1]] = array($retVal[$match[1]], $match[2]); | $retVal[$match[1]] = array($retVal[$match[1]], $match[2]); |
} else { | } else { |
$retVal[$match[1]] = trim($match[2]); | $retVal[$match[1]] = trim($match[2]); |
} | } |
} | } |
} | } |
return $retVal; | return $retVal; |
} | } |
/** | /** |
* HTTP GET | * HTTP GET |
*/ | */ |
function http_get($uri, $data = array()) { | function http_get($uri, $data = array()) { |
$data = (is_array($data)) ? http_build_query($data) : $data; | $data = (is_array($data)) ? http_build_query($data) : $data; |
if (!empty($data)) { | if (!empty($data)) { |
$uri .= "?$data"; | $uri .= "?$data"; |
} | } |
return $this->http_request('GET', $uri); | return $this->http_request('GET', $uri); |
} | } |
/** | /** |
* HTTP PUT | * HTTP PUT |
*/ | */ |
function http_put($uri, $data = array()) { | function http_put($uri, $data = array()) { |
return $this->http_request('PUT', $uri, $data); | return $this->http_request('PUT', $uri, $data); |
} | } |
/** | /** |
* HTTP DELETE | * HTTP DELETE |
*/ | */ |
function http_delete($uri, $data = array()) { | function http_delete($uri, $data = array()) { |
return $this->http_request('DELETE', $uri, $data); | return $this->http_request('DELETE', $uri, $data); |
} | } |
/** | /** |
* Generic implementation of a HTTP Request. | * Generic implementation of a HTTP Request. |
* | * |
* @param $http_method | * @param $http_method |
* @param $uri | * @param $uri |
* @param array $data | * @param array $data |
* @return | * @return |
* an array containing json and decoded versions of the response. | * an array containing json and decoded versions of the response. |
*/ | */ |
private function http_request($http_method, $uri, $data = array()) { | private function http_request($http_method, $uri, $data = array()) { |
$data = (is_array($data)) ? http_build_query($data) : $data; | $data = (is_array($data)) ? http_build_query($data) : $data; |
if (!empty($data)) { | if (!empty($data)) { |
curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen($data))); | curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen($data))); |
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $data); | curl_setopt($this->curl, CURLOPT_POSTFIELDS, $data); |
} | } |
curl_setopt($this->curl, CURLOPT_URL, $this->get_full_url($uri)); | curl_setopt($this->curl, CURLOPT_URL, $this->get_full_url($uri)); |
curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); | curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); |
$response = curl_exec($this->curl); | $response = curl_exec($this->curl); |
$response_decoded = $this->decode_response($response); | $response_decoded = $this->decode_response($response); |
$response = array('json' => $response, 'decoded'=>$response_decoded); | $response = array('json' => $response, 'decoded'=>$response_decoded); |
$this->check_status($response,$uri); | $this->check_status($response,$uri); |
return $response; | return $response; |
} | } |
/** | /** |
* Check http status for safe return codes | * Check http status for safe return codes |
* | * |
* @throws SetteeRestClientException | * @throws SetteeRestClientException |
*/ | */ |
private function check_status($response,$uri) { | private function check_status($response,$uri) { |
$resp_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); | $resp_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); |
if ($resp_code < 199 || $resp_code > 399 || !empty($response['decoded']->error)) { | if ($resp_code < 199 || $resp_code > 399 || !empty($response['decoded']->error)) { |
$msg = "CouchDB returned: \"HTTP 1.1. $resp_code\". ERROR: " . $response['json'] . $uri; | $msg = "CouchDB returned: \"HTTP 1.1. $resp_code\". ERROR: " . $response['json'] . $uri; |
throw new SetteeRestClientException($msg); | throw new SetteeRestClientException($msg); |
} | } |
} | } |
/** | /** |
* @param $path | * @param $path |
* Full path to a file (e.g. as returned by PHP's realpath function). | * Full path to a file (e.g. as returned by PHP's realpath function). |
* @return void | * @return void |
*/ | */ |
public function file_mime_type ($path) { | public function file_mime_type ($path) { |
$ftype = 'application/octet-stream'; | $ftype = 'application/octet-stream'; |
if (function_exists("finfo_file")) { | if (function_exists("finfo_file")) { |
$finfo = new finfo(FILEINFO_MIME_TYPE | FILEINFO_SYMLINK); | $finfo = new finfo(FILEINFO_MIME_TYPE | FILEINFO_SYMLINK); |
$fres = $finfo->file($path); | $fres = $finfo->file($path); |
if (is_string($fres) && !empty($fres)) { | if (is_string($fres) && !empty($fres)) { |
$ftype = $fres; | $ftype = $fres; |
} | } |
} | } |
return $ftype; | return $ftype; |
} | } |
/** | /** |
* @param $content | * @param $content |
* content of a file in a string buffer format. | * content of a file in a string buffer format. |
* @return void | * @return void |
*/ | */ |
public function content_mime_type ($content) { | public function content_mime_type ($content) { |
$ftype = 'application/octet-stream'; | $ftype = 'application/octet-stream'; |
if (function_exists("finfo_file")) { | if (function_exists("finfo_file")) { |
$finfo = new finfo(FILEINFO_MIME_TYPE | FILEINFO_SYMLINK); | $finfo = new finfo(FILEINFO_MIME_TYPE | FILEINFO_SYMLINK); |
$fres = $finfo->buffer($content); | $fres = $finfo->buffer($content); |
if (is_string($fres) && !empty($fres)) { | if (is_string($fres) && !empty($fres)) { |
$ftype = $fres; | $ftype = $fres; |
} | } |
} | } |
return $ftype; | return $ftype; |
} | } |
/** | /** |
* | * |
* @param $json | * @param $json |
* json-encoded response from CouchDB | * json-encoded response from CouchDB |
* | * |
* @return | * @return |
* decoded PHP object | * decoded PHP object |
*/ | */ |
private function decode_response($json) { | private function decode_response($json) { |
return json_decode($json); | return json_decode($json); |
} | } |
/** | /** |
* Get full URL from a partial one | * Get full URL from a partial one |
*/ | */ |
private function get_full_url($uri) { | private function get_full_url($uri) { |
// We do not want "/", "?", "&" and "=" separators to be encoded!!! | // We do not want "/", "?", "&" and "=" separators to be encoded!!! |
$uri = str_replace(array('%2F', '%3F', '%3D', '%26'), array('/', '?', '=', '&'), urlencode($uri)); | $uri = str_replace(array('%2F', '%3F', '%3D', '%26'), array('/', '?', '=', '&'), urlencode($uri)); |
return $this->base_url . '/' . $uri; | return $this->base_url . '/' . $uri; |
} | } |
} | } |
class SetteeRestClientException extends Exception {} | class SetteeRestClientException extends Exception {} |
<?php | <?php |
function include_header_documents($title) { | function include_header_documents($title) { |
header('X-UA-Compatible: IE=edge,chrome=1'); | header('X-UA-Compatible: IE=edge,chrome=1'); |
?> | ?> |
<!doctype html> | <!doctype html> |
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> | <!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> |
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> | <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> |
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> | <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> |
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]--> | <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]--> |
<!-- Consider adding a manifest.appcache: h5bp.com/d/Offline --> | <!-- Consider adding a manifest.appcache: h5bp.com/d/Offline --> |
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> | <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> |
<head> | <head> |
<meta charset="utf-8"> | <meta charset="utf-8"> |
<title>Australian Disclosure Logs<?php if ($title != "") echo " - $title"; ?></title> | <title>Australian Disclosure Logs<?php if ($title != "") echo " - $title"; ?></title> |
<meta name="description" content=""> | <meta name="description" content=""> |
<!-- Mobile viewport optimized: h5bp.com/viewport --> | <!-- Mobile viewport optimized: h5bp.com/viewport --> |
<meta name="viewport" content="width=device-width"> | <meta name="viewport" content="width=device-width"> |
<link rel="alternate" type="application/rss+xml" title="Latest Disclosure Log Entries" href="rss.xml.php" /> | <link rel="alternate" type="application/rss+xml" title="Latest Disclosure Log Entries" href="rss.xml.php" /> |
<!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons --> | <!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons --> |
<meta name="google-site-verification" content="jkknX5g2FCpQvrW030b1Nq2hyoa6mb3EDiA7kCoHNj8" /> | <meta name="google-site-verification" content="jkknX5g2FCpQvrW030b1Nq2hyoa6mb3EDiA7kCoHNj8" /> |
<!-- Le styles --> | <!-- Le styles --> |
<link href="css/bootstrap.min.css" rel="stylesheet"> | <link href="css/bootstrap.min.css" rel="stylesheet"> |
<style type="text/css"> | <style type="text/css"> |
body { | body { |
padding-top: 60px; | padding-top: 60px; |
padding-bottom: 40px; | padding-bottom: 40px; |
} | } |
.sidebar-nav { | .sidebar-nav { |
padding: 9px 0; | padding: 9px 0; |
} | } |
</style> | </style> |
<link href="css/bootstrap-responsive.min.css" rel="stylesheet"> | <link href="css/bootstrap-responsive.min.css" rel="stylesheet"> |
<!-- HTML5 shim, for IE6-8 support of HTML5 elements --> | <!-- HTML5 shim, for IE6-8 support of HTML5 elements --> |
<!--[if lt IE 9]> | <!--[if lt IE 9]> |
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> | <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> |
<![endif]--> | <![endif]--> |
<!-- More ideas for your <head> here: h5bp.com/d/head-Tips --> | <!-- More ideas for your <head> here: h5bp.com/d/head-Tips --> |
<!-- All JavaScript at the bottom, except this Modernizr build. | <!-- All JavaScript at the bottom, except this Modernizr build. |
Modernizr enables HTML5 elements & feature detects for optimal performance. | Modernizr enables HTML5 elements & feature detects for optimal performance. |
Create your own custom Modernizr build: www.modernizr.com/download/ | Create your own custom Modernizr build: www.modernizr.com/download/ |
<script src="js/libs/modernizr-2.5.3.min.js"></script>--> | <script src="js/libs/modernizr-2.5.3.min.js"></script>--> |
<script src="js/jquery.js"></script> | <script src="js/jquery.js"></script> |
<script type="text/javascript" src="js/flotr2.min.js"></script> | <script type="text/javascript" src="js/flotr2.min.js"></script> |
</head> | </head> |
<body> | <body> |
<div class="navbar navbar-inverse navbar-fixed-top"> | <div class="navbar navbar-inverse navbar-fixed-top"> |
<div class="navbar-inner"> | <div class="navbar-inner"> |
<div class="container-fluid"> | <div class="container-fluid"> |
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> | <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> |
<span class="icon-bar"></span> | <span class="icon-bar"></span> |
<span class="icon-bar"></span> | <span class="icon-bar"></span> |
<span class="icon-bar"></span> | <span class="icon-bar"></span> |
</a> | </a> |
<a class="brand" href="#">Australian Disclosure Logs</a> | <a class="brand" href="#">Australian Disclosure Logs</a> |
<div class="nav-collapse collapse"> | <div class="nav-collapse collapse"> |
<p class="navbar-text pull-right"> | <p class="navbar-text pull-right"> |
<small> | <small> |
Subsites on: | Subsites on: |
</small> | </small> |
<a href="http://orgs.disclosurelo.gs">Government Agencies</a> | <a href="http://orgs.disclosurelo.gs">Government Agencies</a> |
• <a href="http://lobbyists.disclosurelo.gs">Political Lobbyists</a> | • <a href="http://lobbyists.disclosurelo.gs">Political Lobbyists</a> |
• <a href="http://contracts.disclosurelo.gs">Government Contracts and Spending</a> | • <a href="http://contracts.disclosurelo.gs">Government Contracts and Spending</a> |
</p> | </p> |
<ul class="nav"> | <ul class="nav"> |
<li><a href="agency.php">By Agency</a></li> | <li><a href="agency.php">By Agency</a></li> |
<li><a href="date.php">By Date</a></li> | <li><a href="date.php">By Date</a></li> |
<li><a href="disclogsList.php">List of Disclosure Logs</a></li> | <li><a href="disclogsList.php">List of Disclosure Logs</a></li> |
<li><a href="about.php">About</a></li> | <li><a href="about.php">About</a></li> |
</ul> | </ul> |
</div><!--/.nav-collapse --> | </div><!--/.nav-collapse --> |
</div> | </div> |
</div> | </div> |
</div> | </div> |
<div class="container"> | <div class="container"> |
<?php | <?php |
} | } |
function include_footer_documents() { | function include_footer_documents() { |
global $ENV; | global $ENV; |
?> | ?> |
</div> <!-- /container --> | </div> <!-- /container --> |
<hr> | <hr> |
<footer> | <footer> |
<p>Not affiliated with or endorsed by any government agency.</p> | <p>Not affiliated with or endorsed by any government agency.</p> |
</footer> | </footer> |
<?php | <?php |
if ($ENV != "DEV") { | if ($ENV != "DEV") { |
echo "<script type='text/javascript'> | echo "<script type='text/javascript'> |
var _gaq = _gaq || []; | var _gaq = _gaq || []; |
_gaq.push(['_setAccount', 'UA-12341040-4']); | _gaq.push(['_setAccount', 'UA-12341040-4']); |
_gaq.push(['_setDomainName', 'disclosurelo.gs']); | _gaq.push(['_setDomainName', 'disclosurelo.gs']); |
_gaq.push(['_setAllowLinker', true]); | _gaq.push(['_setAllowLinker', true]); |
_gaq.push(['_trackPageview']); | _gaq.push(['_trackPageview']); |
(function() { | (function() { |
var ga = document.createElement('script'); | var ga = document.createElement('script'); |
ga.type = 'text/javascript'; | ga.type = 'text/javascript'; |
ga.async = true; | ga.async = true; |
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
var s = document.getElementsByTagName('script')[0]; | var s = document.getElementsByTagName('script')[0]; |
s.parentNode.insertBefore(ga, s); | s.parentNode.insertBefore(ga, s); |
})(); | })(); |
</script>"; | </script>"; |
} | } |
?> | ?> |
<!-- Le javascript | <!-- Le javascript |
================================================== --> | ================================================== --> |
<!-- Placed at the end of the document so the pages load faster --> | <!-- Placed at the end of the document so the pages load faster --> |
<!-- | <!-- |
<script src="js/bootstrap-transition.js"></script> | <script src="js/bootstrap-transition.js"></script> |
<script src="js/bootstrap-alert.js"></script> | <script src="js/bootstrap-alert.js"></script> |
<script src="js/bootstrap-modal.js"></script> | <script src="js/bootstrap-modal.js"></script> |
<script src="js/bootstrap-dropdown.js"></script> | <script src="js/bootstrap-dropdown.js"></script> |
<script src="js/bootstrap-scrollspy.js"></script> | <script src="js/bootstrap-scrollspy.js"></script> |
<script src="js/bootstrap-tab.js"></script> | <script src="js/bootstrap-tab.js"></script> |
<script src="js/bootstrap-tooltip.js"></script> | <script src="js/bootstrap-tooltip.js"></script> |
<script src="js/bootstrap-popover.js"></script> | <script src="js/bootstrap-popover.js"></script> |
<script src="js/bootstrap-button.js"></script> | <script src="js/bootstrap-button.js"></script> |
<script src="js/bootstrap-collapse.js"></script> | <script src="js/bootstrap-collapse.js"></script> |
<script src="js/bootstrap-carousel.js"></script> | <script src="js/bootstrap-carousel.js"></script> |
<script src="js/bootstrap-typeahead.js"></script>--> | <script src="js/bootstrap-typeahead.js"></script>--> |
</body> | </body> |
</html> | </html> |
<?php | <?php |
} | } |
function truncate($string, $length, $stopanywhere = false) { | function truncate($string, $length, $stopanywhere = false) { |
//truncates a string to a certain char length, stopping on a word if not specified otherwise. | //truncates a string to a certain char length, stopping on a word if not specified otherwise. |
if (strlen($string) > $length) { | if (strlen($string) > $length) { |
//limit hit! | //limit hit! |
$string = substr($string, 0, ($length - 3)); | $string = substr($string, 0, ($length - 3)); |
if ($stopanywhere) { | if ($stopanywhere) { |
//stop anywhere | //stop anywhere |
$string .= '...'; | $string .= '...'; |
} else { | } else { |
//stop on a word. | //stop on a word. |
$string = substr($string, 0, strrpos($string, ' ')) . '...'; | $string = substr($string, 0, strrpos($string, ' ')) . '...'; |
} | } |
} | } |
return $string; | return $string; |
} | } |
function displayLogEntry($row, $idtoname) { | function displayLogEntry($row, $idtoname) { |
$result = ""; | $result = ""; |
$result .= '<div itemscope itemtype="http://schema.org/Article">'; | $result .= '<div itemscope itemtype="http://schema.org/Article">'; |
$result .= '<h2> <span itemprop="datePublished">' . $row->value->date . "</span>: <span itemprop='name headline'>" . truncate($row->value->title, 120) . "</span>"; | $result .= '<h2><a href="http://disclosurelo.gs/view.php?id='.$row->value->_id.'"> <span itemprop="datePublished">' . $row->value->date . "</span>: <span itemprop='name headline'>" . truncate($row->value->title, 120) . "</span>"; |
$result .= ' (<span itemprop="author publisher creator">' . $idtoname[$row->value->agencyID] . '</span>)</h2>'; | $result .= ' (<span itemprop="author publisher creator">' . $idtoname[$row->value->agencyID] . '</span>)</a></h2>'; |
$result .= "<p itemprop='description articleBody text'> Title: " . $row->value->title . "<br/>"; | $result .= "<p itemprop='description articleBody text'> Title: " . $row->value->title . "<br/>"; |
if (isset($row->value->description)) { | if (isset($row->value->description)) { |
$result .= str_replace("\n", "<br>", preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "",trim($row->value->description))); | $result .= str_replace("\n", "<br>", preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "",trim($row->value->description))); |
} | } |
if (isset($row->value->notes)) { | if (isset($row->value->notes)) { |
$result .= " <br>Note: " . $row->value->notes; | $result .= " <br>Note: " . $row->value->notes; |
} | } |
$result .= "</p>"; | $result .= "</p>"; |
if (isset($row->value->links)) { | if (isset($row->value->links)) { |
$result .= '<h3>Links/Documents</h3><ul itemprop="associatedMedia">'; | $result .= '<h3>Links/Documents</h3><ul itemprop="associatedMedia">'; |
foreach ($row->value->links as $link) { | foreach ($row->value->links as $link) { |
$result .= '<li itemscope itemtype="http://schema.org/MediaObject"><a href="' . htmlspecialchars ($link) . '" itemprop="url contentURL">' . htmlspecialchars ( $link) . "</a></li>"; | $result .= '<li itemscope itemtype="http://schema.org/MediaObject"><a href="' . htmlspecialchars ($link) . '" itemprop="url contentURL">' . htmlspecialchars ( $link) . "</a></li>"; |
} | } |
$result .= "</ul>"; | $result .= "</ul>"; |
} | } |
$result .= "<small><A itemprop='url' href='" . $row->value->url . "'>View original source...</a> ID: " . strip_tags($row->value->docID) . "</small>"; | $result .= "<small><A itemprop='url' href='" . $row->value->url . "'>View original source...</a> ID: " . strip_tags($row->value->docID) . "</small>"; |
$result .= "</div>\n"; | $result .= "</div>\n"; |
return $result; | return $result; |
} | } |
<?php | <?php |
date_default_timezone_set("Australia/Sydney"); | date_default_timezone_set("Australia/Sydney"); |
$basePath = ""; | $basePath = ""; |
if (strstr($_SERVER['PHP_SELF'], "alaveteli/") | if (strstr($_SERVER['PHP_SELF'], "alaveteli/") |
|| strstr($_SERVER['PHP_SELF'], "admin/") | || strstr($_SERVER['PHP_SELF'], "admin/") |
|| strstr($_SERVER['PHP_SELF'], "lib/") | || strstr($_SERVER['PHP_SELF'], "lib/") |
|| strstr($_SERVER['PHP_SELF'], "include/") | || strstr($_SERVER['PHP_SELF'], "include/") |
|| strstr($_SERVER['PHP_SELF'], "documents/") | || strstr($_SERVER['PHP_SELF'], "documents/") |
|| $_SERVER['SERVER_NAME'] == "disclosurelo.gs" | || $_SERVER['SERVER_NAME'] == "disclosurelo.gs" |
|| $_SERVER['SERVER_NAME'] == "www.disclosurelo.gs" | |
) | ) |
$basePath = "../"; | $basePath = "../"; |
include_once ('couchdb.inc.php'); | include_once ('couchdb.inc.php'); |
include_once ('template.inc.php'); | include_once ('template.inc.php'); |
require_once $basePath.'lib/Requests/library/Requests.php'; | require_once $basePath.'lib/Requests/library/Requests.php'; |
Requests::register_autoloader(); | Requests::register_autoloader(); |
$ENV = "DEV"; | $ENV = "DEV"; |
if (isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME'] != 'localhost') { | if (isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME'] != 'localhost') { |
require $basePath."lib/amon-php/amon.php"; | require $basePath."lib/amon-php/amon.php"; |
Amon::config(array('address'=> 'http://127.0.0.1:2464', | Amon::config(array('address'=> 'http://127.0.0.1:2464', |
'protocol' => 'http', | 'protocol' => 'http', |
'secret_key' => "I2LJ6dOMmlnXgVAkTPFXd5M3ejkga8Gd2FbBt6iqZdw")); | 'secret_key' => "I2LJ6dOMmlnXgVAkTPFXd5M3ejkga8Gd2FbBt6iqZdw")); |
Amon::setup_exception_handler(); | Amon::setup_exception_handler(); |
$ENV = "PROD"; | $ENV = "PROD"; |
} | } |
# Convert a stdClass to an Array. http://www.php.net/manual/en/language.types.object.php#102735 | # Convert a stdClass to an Array. http://www.php.net/manual/en/language.types.object.php#102735 |
function object_to_array(stdClass $Class) { | function object_to_array(stdClass $Class) { |
# Typecast to (array) automatically converts stdClass -> array. | # Typecast to (array) automatically converts stdClass -> array. |
$Class = (array) $Class; | $Class = (array) $Class; |
# Iterate through the former properties looking for any stdClass properties. | # Iterate through the former properties looking for any stdClass properties. |
# Recursively apply (array). | # Recursively apply (array). |
foreach ($Class as $key => $value) { | foreach ($Class as $key => $value) { |
if (is_object($value) && get_class($value) === 'stdClass') { | if (is_object($value) && get_class($value) === 'stdClass') { |
$Class[$key] = object_to_array($value); | $Class[$key] = object_to_array($value); |
} | } |
} | } |
return $Class; | return $Class; |
} | } |
# Convert an Array to stdClass. http://www.php.net/manual/en/language.types.object.php#102735 | # Convert an Array to stdClass. http://www.php.net/manual/en/language.types.object.php#102735 |
function array_to_object(array $array) { | function array_to_object(array $array) { |
# Iterate through our array looking for array values. | # Iterate through our array looking for array values. |
# If found recurvisely call itself. | # If found recurvisely call itself. |
foreach ($array as $key => $value) { | foreach ($array as $key => $value) { |
if (is_array($value)) { | if (is_array($value)) { |
$array[$key] = array_to_object($value); | $array[$key] = array_to_object($value); |
} | } |
} | } |
# Typecast to (object) will automatically convert array -> stdClass | # Typecast to (object) will automatically convert array -> stdClass |
return (object) $array; | return (object) $array; |
} | } |
function dept_to_portfolio($deptName) { | function dept_to_portfolio($deptName) { |
return trim(str_replace("Department of", "", str_replace("Department of the", "Department of", $deptName))); | return trim(str_replace("Department of", "", str_replace("Department of the", "Department of", $deptName))); |
} | } |
function phrase_to_tag ($phrase) { | function phrase_to_tag ($phrase) { |
return str_replace(" ","_",str_replace("'","",str_replace(",","",strtolower($phrase)))); | return str_replace(" ","_",str_replace("'","",str_replace(",","",strtolower($phrase)))); |
} | } |
function local_url() { | function local_url() { |
return "http://" . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\') . "/"; | return "http://" . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\') . "/"; |
} | } |
function GetDomain($url) | function GetDomain($url) |
{ | { |
$nowww = ereg_replace('www\.','',$url); | $nowww = ereg_replace('www\.','',$url); |
$domain = parse_url($nowww); | $domain = parse_url($nowww); |
if(!empty($domain["host"])) | if(!empty($domain["host"])) |
{ | { |
return $domain["host"]; | return $domain["host"]; |
} else | } else |
{ | { |
return $domain["path"]; | return $domain["path"]; |
} | } |
} | } |