forked from opencaching/okapi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
issue opencaching#601 upload fieldnotes
- Loading branch information
Showing
2 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
<?php | ||
|
||
namespace okapi\services\fieldnotes\upload; | ||
|
||
use okapi\core\Exception\InvalidParam; | ||
use okapi\core\Exception\ParamMissing; | ||
use okapi\core\Db; | ||
use okapi\core\Okapi; | ||
use okapi\core\OkapiServiceRunner; | ||
use okapi\core\Request\OkapiInternalRequest; | ||
use okapi\core\Request\OkapiRequest; | ||
use okapi\services\logs\LogsCommon; | ||
use okapi\Settings; | ||
|
||
class WebService | ||
{ | ||
public static function options() | ||
{ | ||
return array( | ||
'min_auth_level' => 3 | ||
); | ||
} | ||
|
||
public static function call(OkapiRequest $request) | ||
{ | ||
$result = array( | ||
'success' => false // if the installation doesn't support it | ||
); | ||
|
||
if (Settings::get('OC_BRANCH') == 'oc.de') | ||
{ | ||
|
||
$field_notes = $request->get_parameter('field_notes'); | ||
if (!$field_notes) throw new ParamMissing('field_notes'); | ||
|
||
$result = Okapi::get_submittable_logtype_names(); | ||
$result = json_encode($result, JSON_PRETTY_PRINT); // debug | ||
return Okapi::formatted_response($request, $result); | ||
|
||
$notes = self::parse_notes($field_notes); | ||
if ($notes === false) throw new InvalidParam('field_notes', "Input data not recognized."); | ||
|
||
foreach ($notes as $n) | ||
{ | ||
$geocache = OkapiServiceRunner::call( | ||
'services/caches/geocache', | ||
new OkapiInternalRequest($request->consumer, $request->token, array( | ||
'cache_code' => $n['code'], | ||
'fields' => 'internal_id' | ||
)) | ||
); | ||
$user_id = $request->token->user_id; | ||
$geocache_id = $geocache['internal_id']; | ||
$type = Okapi::logtypename2id($n['type']); | ||
$date = date("Y-m-d H:i:s", strtotime($n['date'])); | ||
$text = $n['log']; | ||
|
||
Db::query(" | ||
insert into field_note ( | ||
user_id, geocache_id, type, date, text | ||
) values ( | ||
'".Db::escape_string($user_id)."', | ||
'".Db::escape_string($geocache_id)."', | ||
'".Db::escape_string($type)."', | ||
'".Db::escape_string($date)."', | ||
'".Db::escape_string($text)."' | ||
) | ||
"); | ||
|
||
} | ||
$result = array( | ||
'success' => true | ||
); | ||
//$result = json_encode($notes, JSON_PRETTY_PRINT); // debug | ||
} | ||
return Okapi::formatted_response($request, $result); | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
|
||
private static function parse_notes($field_notes) | ||
{ | ||
$decoded_field_notes = base64_decode($field_notes, true); | ||
if ($decoded_field_notes === false) return false; | ||
|
||
$multiline = self::fieldNotesTxtArea2Array($decoded_field_notes); | ||
|
||
$parsed_records = []; | ||
|
||
foreach ($multiline as $line) { | ||
$line = trim($line); | ||
$fields = self::CSVtoArray($line); | ||
|
||
$code = $fields[0]; | ||
$date = $fields[1]; | ||
$type = $fields[2]; | ||
$log = nl2br($fields[3]); | ||
|
||
$parsed_records[] = [ | ||
'code' => $code, | ||
'date' => $date, | ||
'type' => $type, | ||
'log' => $log, | ||
]; | ||
} | ||
return $parsed_records; | ||
} | ||
|
||
|
||
// ------------------------------------------------------------------ | ||
|
||
private static function fieldNotesTxtArea2Array($fieldnotes) | ||
{ | ||
$output = []; | ||
$buffer = ''; | ||
$start = true; | ||
|
||
$lines = explode("\n", $fieldnotes); | ||
$lines = array_filter($lines); // Drop empty lines | ||
|
||
foreach ($lines as $line) { | ||
if ($start) { | ||
$buffer = $line; | ||
$start = false; | ||
} else { | ||
if (strpos($line, 'OC') !== 0) { | ||
$buffer .= "\n" . $line; | ||
} else { | ||
$output[] = trim($buffer); | ||
$buffer = $line; | ||
} | ||
} | ||
} | ||
|
||
if (!$start) { | ||
$output[] = trim($buffer); | ||
} | ||
|
||
return $output; | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
|
||
private static function CSVtoArray($text) | ||
{ | ||
$ret = ['']; | ||
$i = 0; | ||
$p = ''; | ||
$s = true; | ||
|
||
foreach (str_split($text) as $l) { | ||
if ('"' === $l) { | ||
$s = !$s; | ||
if ('"' === $p) { | ||
$ret[$i] .= '"'; | ||
$l = '-'; | ||
} elseif ('' === $p) { | ||
$l = '-'; | ||
} | ||
} elseif ($s && ',' === $l) { | ||
$l = $ret[++$i] = ''; | ||
} else { | ||
$ret[$i] .= $l; | ||
} | ||
$p = $l; | ||
} | ||
|
||
return $ret; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<xml> | ||
<brief>Upload Fieldnotes</brief> | ||
<issue-id>630</issue-id> | ||
<desc> | ||
<p>Upload a set of one or more fieldnotes records.</p> | ||
</desc> | ||
<req name='field_notes'> | ||
<p>Fieldnotes consist of one or more records in CSV format. Each | ||
record comprises a geocache log consisting of four fields:</p> | ||
<ul> | ||
<li>Geocache Code</li> | ||
<li>Date</li> | ||
<li>Log Type</li> | ||
<li>Log Text</li> | ||
</ul> | ||
<p>The first three fields are simple entities, the Log Text field is | ||
different and a bit difficult as it may spread over muliple lines | ||
and it may contain quote characters. In order to preserve the structure | ||
of the records, the <i>field_notes</i> parameter must be passed as a | ||
<b>base64 encoded utf8 string</b>. UTF-16LE, UTF-16BE with or without | ||
BOM are not supported. | ||
</p> | ||
<p>Since the log type is passed as a string, its value must match the | ||
values supported by the platform (case sensitive!): | ||
<pre> | ||
[ | ||
"Found it", | ||
"Didn't find it", | ||
"Comment", | ||
"Attended", | ||
"Will attend", | ||
"Archived", | ||
"Ready to search", | ||
"Temporarily unavailable" | ||
] | ||
</pre> | ||
</p> | ||
<p>Note: This service method is not supported on all installations</p> | ||
</req> | ||
<common-format-params/> | ||
<returns> | ||
<p>A dictionary of the following structure:</p> | ||
<ul> | ||
<li>success - true</li> | ||
</ul> | ||
</returns> | ||
</xml> |