Skip to content

Commit

Permalink
Core (fix): improved toUTF8 and getUTF8Char methods / Class (add): i…
Browse files Browse the repository at this point in the history
…mproved camelCase method, added deCamelCase method / Reader (fix): improved auth and port handling / Resource (fix): nasty typo fixed in setProp method (thx to Stephane Corlosquet) / getFormat (fix): improved SPARQL results detection / TurtleParser (fix): improved WS/non-WS handling around CURIEs (thx to Stephane Corlosquet) / RDFJSONSerializer (fix): improved escaping (thx to Gareth Jones) / RDFXMLSerializer (fix): improved QName generation / RemoteStore (fix): memory leaked (thx to Paul Houle) / DeleteQueryHandler (fix): less greedy triple deletion when datatype or language are declared (thx to Nicholas Rawlings) / LoadQueryHandler (tweak): getOComp now always keeps some trailing chars for improved sorting of URIs / SelectQueryHandler (fix): improved cleanup of temp tables in case of unexpected MySQL errors
  • Loading branch information
Benjamin Nowack committed Feb 23, 2010
1 parent 4e06cb5 commit e699756
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 55 deletions.
11 changes: 7 additions & 4 deletions ARC2.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
* @license <http://arc.semsol.org/license>
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2010-01-15
* @version 2010-02-23
*/

class ARC2 {

function getVersion() {
return '2010-01-15';
return '2010-02-23';
}

/* */
Expand Down Expand Up @@ -120,14 +120,17 @@ function getPreferredFormat($default = 'plain') {
/* */

function toUTF8($v) {
if (utf8_decode($v) == $v) return $v;
if (urlencode($v) === $v) return $v;
//if (utf8_decode($v) == $v) return $v;
$v = (strpos(utf8_decode(str_replace('?', '', $v)), '?') === false) ? utf8_decode($v) : $v;
return preg_replace_callback('/([\x00-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3}|[\xf8-\xfb][\x80-\xbf]{4}|[\xfc-\xfd][\x80-\xbf]{5}|[^\x00-\x7f])/', array('ARC2', 'getUTF8Char'), $v);
}

function getUTF8Char($v) {
$val = $v[1];
return (strlen(trim($val)) === 1) ? utf8_encode($val) : $val;
if (strlen(trim($val)) === 1) return utf8_encode($val);
if (preg_match('/^([\x00-\x7f])(.+)/', $val, $m)) return $m[1] . ARC2::toUTF8($m[2]);
return $val;
}

/* */
Expand Down
12 changes: 9 additions & 3 deletions ARC2_Class.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license <http://arc.semsol.org/license>
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2009-12-08
* @version 2010-02-17
*/

class ARC2_Class {
Expand Down Expand Up @@ -68,10 +68,16 @@ function m($name, $a = false, $default = false, $o = false) {/* call method */

function camelCase($v, $lc_first = 0) {
$r = ucfirst($v);
while (preg_match('/^(.*)[\-\_ ](.*)$/', $r, $m)) {
while (preg_match('/^(.*)[^a-z0-9](.*)$/si', $r, $m)) {
$r = $m[1] . ucfirst($m[2]);
}
return $lc_first ? strtolower(substr($r, 0, 1)) . substr($r, 1) : $r;
return $lc_first && !preg_match('/[A-Z]/', $r[1]) ? strtolower($r[0]) . substr($r, 1) : $r;
}

function deCamelCase($v, $uc_first = 0) {
$r = str_replace('_', ' ', $v);
$r = preg_replace('/([a-z])([A-Z])/e', '"\\1 " . strtolower("\\2")', $r);
return $uc_first ? ucfirst($r) : $r;
}

/* */
Expand Down
11 changes: 6 additions & 5 deletions ARC2_Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license <http://arc.semsol.org/license>
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2009-12-08
* @version 2010-01-30
*/

ARC2::inc('Class');
Expand Down Expand Up @@ -133,7 +133,7 @@ function setCredentials($url) {
}
/* add header */
if ($auth) {
$this->setCustomHeaders('Authorization: ' . $auth);
$this->addCustomHeaders('Authorization: ' . $auth);
break;
}
}
Expand Down Expand Up @@ -199,8 +199,9 @@ function getHTTPSocket($url, $redirs = 0) {
else {
$h_code = $http_mthd . ' ' . $this->v1('path', '/', $parts) . (($v = $this->v1('query', 0, $parts)) ? '?' . $v : '') . (($v = $this->v1('fragment', 0, $parts)) ? '#' . $v : '');
}
$port_code = ($parts['port'] != 80) ? ':' . $parts['port'] : '';
$h_code .= ' HTTP/1.0' . $nl.
'Host: ' . $parts['host'] . ':' . $parts['port'] . $nl .
'Host: ' . $parts['host'] . $port_code . $nl .
(($v = $this->http_accept_header) ? $v . $nl : '') .
(($v = $this->http_user_agent_header) && !preg_match('/User\-Agent\:/', $this->http_custom_headers) ? $v . $nl : '') .
(($http_mthd == 'POST') ? 'Content-Length: ' . strlen($this->message_body) . $nl : '') .
Expand All @@ -223,7 +224,7 @@ function getHTTPSocket($url, $redirs = 0) {
stream_context_set_option($context, 'ssl', $m[1], $v);
}
}
$s = stream_socket_client('ssl://' . $parts['host'] . ':' . $parts['port'], $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $context);
$s = stream_socket_client('ssl://' . $parts['host'] . $port_code, $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $context);
}
elseif ($parts['scheme'] == 'https') {
$s = @fsockopen('ssl://' . $parts['host'], $parts['port'], $errno, $errstr, $this->timeout);
Expand Down Expand Up @@ -285,7 +286,7 @@ function getHTTPSocket($url, $redirs = 0) {
$this->digest_auth = 1;
return $this->getHTTPSocket($url);
}
return $this->addError($error . ' "' . (!feof($s) ? trim(strip_tags(fread($s, 64))) . '..."' : ''));
return $this->addError($error . ' "' . (!feof($s) ? trim(strip_tags(fread($s, 128))) . '..."' : ''));
}
/* redirect */
if ($this->v('redirect', 0, $h) && ($new_url = $this->v1('location', 0, $h))) {
Expand Down
4 changes: 2 additions & 2 deletions ARC2_Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license http://arc.semsol.org/license
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2009-11-26
* @version 2010-02-23
*/

ARC2::inc('Class');
Expand Down Expand Up @@ -52,7 +52,7 @@ function setProp($p, $os, $s = '') {
if (isset($os['value'])) $os = array($os);
/* list of values */
foreach ($os as $i => $o) {
if (!is_array($o)) $os[i] = array('value' => $o, 'type' => 'literal');
if (!is_array($o)) $os[$i] = array('value' => $o, 'type' => 'literal');
}
$this->index[$s][$this->expandPName($p)] = $os;
}
Expand Down
7 changes: 4 additions & 3 deletions ARC2_getFormat.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @author Benjamin Nowack <[email protected]>
* @license http://arc.semsol.org/license
* @package ARC2
* @version 2009-10-16
* @version 2010-01-18
*/

function ARC2_getFormat($v, $mtype = '', $ext = '') {
Expand All @@ -15,6 +15,7 @@ function ARC2_getFormat($v, $mtype = '', $ext = '') {
$r = (!$r && preg_match('/\/rdf\+xml/', $mtype)) ? 'rdfxml' : $r;
$r = (!$r && preg_match('/\/(x\-)?turtle/', $mtype)) ? 'turtle' : $r;
$r = (!$r && preg_match('/\/rdf\+n3/', $mtype)) ? 'n3' : $r;
$r = (!$r && preg_match('/\/sparql-results\+xml/', $mtype)) ? 'sparqlxml' : $r;
/* xml sniffing */
if (
!$r &&
Expand All @@ -23,7 +24,7 @@ function ARC2_getFormat($v, $mtype = '', $ext = '') {
/* has an xmlns:* declaration or a matching pair of tags */
(preg_match('/\sxmlns\:?/', $v) || preg_match('/\<([^\s]+).+\<\/\\1\>/s', $v)) &&
/* not a typical ntriples/turtle/n3 file */
!preg_match('/\.\s*$/s', $v)
!preg_match('/[\>\"\']\s*\.\s*$/s', $v)
) {
while (preg_match('/^\s*\<\?xml[^\r\n]+\?\>\s*/s', $v)) {
$v = preg_replace('/^\s*\<\?xml[^\r\n]+\?\>\s*/s', '', $v);
Expand All @@ -41,7 +42,7 @@ function ARC2_getFormat($v, $mtype = '', $ext = '') {
$r = (!$r && preg_match('/^\s*\<opml\s/s', $v)) ? 'opml' : $r;
$r = (!$r && preg_match('/^\s*\<html[\s|\>]/is', $v)) ? 'html' : $r;
$r = (!$r && preg_match('/^\s*\<sparql\s+[^\>]+http\:\/\/www\.w3\.org\/2005\/sparql\-results\#/s', $v)) ? 'sparqlxml' : $r;
$r = (!$r && preg_match('/^\s*\<[^\>]+http\:\/\/www\.w3\.org\/2005\/sparql\-results#/s', $v)) ? 'srx' : $r;
$r = (!$r && preg_match('/^\s*\<[^\>]+http\:\/\/www\.w3\.org\/2005\/sparql\-results#/s', $v)) ? 'srx' : $r;
$r = (!$r && preg_match('/^\s*\<[^\s]*RDF[\s\>]/s', $v)) ? 'rdfxml' : $r;
$r = (!$r && preg_match('/^\s*\<[^\>]+http\:\/\/www\.w3\.org\/1999\/02\/22\-rdf/s', $v)) ? 'rdfxml' : $r;

Expand Down
4 changes: 2 additions & 2 deletions parsers/ARC2_TurtleParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license <http://arc.semsol.org/license>
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2009-11-16
* @version 2010-02-16
*/

ARC2::inc('RDFParser');
Expand Down Expand Up @@ -831,7 +831,7 @@ function xPN_LOCAL($v) {
$proceed = 1;
}
elseif ($r) {
if (($sub_r = $this->x('(\.)', $sub_v)) && !preg_match('/^\s/s', $sub_r[2])) {
if (($sub_r = $this->x('(\.)', $sub_v)) && !preg_match('/^[\s\}]/s', $sub_r[2])) {
$r .= $sub_r[1];
$sub_v = $sub_r[2];
}
Expand Down
21 changes: 11 additions & 10 deletions serializers/ARC2_RDFJSONSerializer.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?php
/*
homepage: http://arc.semsol.org/
license: http://arc.semsol.org/license
class: ARC2 RDF/JSON Serializer
author: Benjamin Nowack
version: 2008-07-01 (Fix: Proper jsonEscape method, thx to Keith Alexander)
/**
* ARC2 RDF/JSON Serializer
*
* @author Benjamin Nowack <[email protected]>
* @license http://arc.semsol.org/license
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2010-02-23
*/

ARC2::inc('RDFSerializer');
Expand Down Expand Up @@ -39,12 +40,12 @@ function getTerm($v, $term = 's') {
return $this->getTerm($v['value'], $term);
}
if (preg_match('/^\_\:/', $v['value'])) {
return '{ "value" : "' . $v['value']. '", "type" : "bnode" }';
return '{ "value" : "' . $this->jsonEscape($v['value']) . '", "type" : "bnode" }';
}
return '{ "value" : "' . $v['value']. '", "type" : "uri" }';
return '{ "value" : "' . $this->jsonEscape($v['value']) . '", "type" : "uri" }';
}
/* literal */
$r = '{ "value" : "' . $this->jsonEscape($v['value']). '", "type" : "literal"';
$r = '{ "value" : "' . $this->jsonEscape($v['value']) . '", "type" : "literal"';
$suffix = isset($v['datatype']) ? ', "datatype" : "' . $v['datatype'] . '"' : '';
$suffix = isset($v['lang']) ? ', "lang" : "' . $v['lang'] . '"' : $suffix;
$r .= $suffix . ' }';
Expand Down
5 changes: 3 additions & 2 deletions serializers/ARC2_RDFXMLSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license <http://arc.semsol.org/license>
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2009-12-03
* @version 2010-01-30
*
*/

Expand Down Expand Up @@ -79,7 +79,8 @@ function getTerm($v, $type) {

function getPName($v, $connector = ':') {
if ($this->default_ns && (strpos($v, $this->default_ns) === 0)) {
return substr($v, strlen($this->default_ns));
$pname = substr($v, strlen($this->default_ns));
if (!preg_match('/\//', $pname)) return $pname;
}
return parent::getPName($v, $connector);
}
Expand Down
24 changes: 17 additions & 7 deletions store/ARC2_RemoteStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @author Benjamin Nowack <[email protected]>
* @license http://arc.semsol.org/license
* @package ARC2
* @version 2009-12-08
* @version 2010-02-23
*/

ARC2::inc('Class');
Expand Down Expand Up @@ -144,16 +144,26 @@ function runQuery($q, $qt = '', $infos = '') {
/* ask|load|insert|delete */
if (in_array($qt, array('ask', 'load', 'insert', 'delete'))) {
$bid = $parser->getBooleanInsertedDeleted();
switch ($qt) {
case 'ask': return $bid['boolean'];
default: return $bid;
if ($qt == 'ask') {
$r = $bid['boolean'];
}
else {
$r = $bid;
}
}
/* select */
if (($qt == 'select') && !method_exists($parser, 'getRows')) return $resp;
if ($qt == 'select') return array('rows' => $parser->getRows(), 'variables' => $parser->getVariables());
elseif (($qt == 'select') && !method_exists($parser, 'getRows')) {
$r = $resp;
}
elseif ($qt == 'select') {
$r = array('rows' => $parser->getRows(), 'variables' => $parser->getVariables());
}
/* any other */
return $parser->getSimpleIndex(0);
else {
$r = $parser->getSimpleIndex(0);
}
unset($parser);
return $r;
}

/* */
Expand Down
26 changes: 17 additions & 9 deletions store/ARC2_StoreDeleteQueryHandler.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?php
/*
homepage: http://arc.semsol.org/
license: http://arc.semsol.org/license
class: ARC2 RDF Store DELETE Query Handler
author: Benjamin Nowack
version: 2009-06-15 (Addition: cleanValueTables method)
/**
* ARC2 RDF Store DELETE Query Handler
*
* @author Benjamin Nowack <[email protected]>
* @license http://arc.semsol.org/license
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2010-02-23
*/

ARC2::inc('StoreQueryHandler');
Expand Down Expand Up @@ -103,8 +104,15 @@ function deleteTriples() {
}
else {
$term_id = $this->getTermID($t[$term], $term);
$q .= $q ? ' AND ' : '';
$q .= 'T.' . $term . '=' . $term_id;
$q .= ($q ? ' AND ' : '') . 'T.' . $term . '=' . $term_id;
/* explicit lang/dt restricts the matching */
if ($term == 'o') {
$o_lang = $this->v1('o_lang', '', $t);
$o_lang_dt = $this->v1('o_datatype', $o_lang, $t);
if ($o_lang_dt) {
$q .= ($q ? ' AND ' : '') . 'T.o_lang_dt=' . $this->getTermID($o_lang_dt, 'lang_dt');
}
}
}
}
if ($skip) {
Expand Down
7 changes: 5 additions & 2 deletions store/ARC2_StoreLoadQueryHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license <http://arc.semsol.org/license>
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2010-01-14
* @version 2010-02-17
*/

ARC2::inc('StoreQueryHandler');
Expand Down Expand Up @@ -303,7 +303,10 @@ function getOComp($val) {
//$val = substr(trim(preg_replace('/[\W\s]+/is', '-', strip_tags($val))), 0, 35);
$re = $this->has_pcre_unicode ? '/[\PL\s]+/isu' : '/[\s\'\"\´\`]+/is';
$val = trim(preg_replace($re, '-', strip_tags($val)));
$val = function_exists("mb_substr") ? mb_substr($val, 0, 35) : substr($val, 0, 35);
if (strlen($val) > 35) {
$fnc = function_exists("mb_substr") ? 'mb_substr' : 'substr';
$val = $fnc($val, 0, 17) . '-' . $fnc($val, -17);
}
if ($this->strip_mb_comp_str) {
$val = urldecode(preg_replace('/\%[0-9A-F]{2}/', '', urlencode($val)));
}
Expand Down
10 changes: 4 additions & 6 deletions store/ARC2_StoreSelectQueryHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license http://arc.semsol.org/license
* @homepage <http://arc.semsol.org/>
* @package ARC2
* @version 2010-01-04
* @version 2010-02-12
*
*/

Expand Down Expand Up @@ -108,10 +108,10 @@ function createTempTable($q_sql) {
$con = $this->store->getDBCon();
$v = $this->store->getDBVersion();
if ($this->cache_results) {
$tbl = $this->store->getTablePrefix() . '_Q' . md5($q_sql);
$tbl = $this->store->getTablePrefix() . 'Q' . md5($q_sql);
}
else {
$tbl = $this->store->getTablePrefix() . '_Q' . md5($q_sql . time() . uniqid(rand()));
$tbl = $this->store->getTablePrefix() . 'Q' . md5($q_sql . time() . uniqid(rand()));
}
if (strlen($tbl) > 64) $tbl = 'Q' . md5($tbl);
$tmp_sql = 'CREATE TEMPORARY TABLE ' . $tbl . ' ( ' . $this->getTempTableDef($tbl, $q_sql) . ') ';
Expand All @@ -121,9 +121,7 @@ function createTempTable($q_sql) {
return $this->addError(mysql_error($con));
}
mysql_unbuffered_query('INSERT INTO ' . $tbl . ' ' . "\n" . $q_sql, $con);
if ($er = mysql_error($con)) {
return $this->addError($er);
}
if ($er = mysql_error($con)) $this->addError($er);
return $tbl;
}

Expand Down

0 comments on commit e699756

Please sign in to comment.