Skip to content
This repository was archived by the owner on Mar 30, 2024. It is now read-only.

Commit b9f7ffb

Browse files
committed
Add autocompletes of #3
1 parent be23a99 commit b9f7ffb

File tree

8 files changed

+262
-59
lines changed

8 files changed

+262
-59
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
latest
2-
0.2.5
2+
0.2.6
33
0.2
44
0

php/ajax.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* TaskTimeTerminate Sync-Server
4+
* https://github.com/KIMB-technologies/TaskTimeTerminate
5+
*
6+
* (c) 2020 KIMB-technologies
7+
* https://github.com/KIMB-technologies/
8+
*
9+
* released under the terms of GNU Public License Version 3
10+
* https://www.gnu.org/licenses/gpl-3.0.txt
11+
*/
12+
define( 'TaskTimeTerminate', 'GUI' );
13+
14+
require_once( __DIR__ . '/core/load.php' );
15+
16+
$output = array();
17+
$login = new Login();
18+
if( $login->isLoggedIn() ){
19+
if(!empty($_GET['term']) && !empty($_GET['type']) &&
20+
is_string($_GET['term']) && is_string($_GET['type']) &&
21+
preg_match('/^[A-Za-z0-9\_\-\,]+$/', $_GET['term']) === 1
22+
){
23+
$acs = new Autocomplete($login);
24+
switch( $_GET['type'] ){
25+
case 'category':
26+
$output = $acs->completeCategory($_GET['term']);
27+
break;
28+
case 'task':
29+
$output = $acs->completeTask($_GET['term']);
30+
break;
31+
default:
32+
$output['error'] = "Unknown type!";
33+
}
34+
}
35+
else{
36+
$output['error'] = "Unknown request!";
37+
}
38+
}
39+
else {
40+
$output['error'] = "Not logged in!";
41+
}
42+
43+
header('Content-Type: application/json; charset=utf-8');
44+
if(isset($output['error'])){
45+
http_response_code(401);
46+
}
47+
echo json_encode($output, JSON_PRETTY_PRINT);
48+
?>

php/core/Autocomplete.php

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
/**
3+
* TaskTimeTerminate Sync-Server
4+
* https://github.com/KIMB-technologies/TaskTimeTerminate
5+
*
6+
* (c) 2020 KIMB-technologies
7+
* https://github.com/KIMB-technologies/
8+
*
9+
* released under the terms of GNU Public License Version 3
10+
* https://www.gnu.org/licenses/gpl-3.0.txt
11+
*/
12+
defined( 'TaskTimeTerminate' ) or die('Invalid Endpoint!');
13+
14+
class Autocomplete {
15+
16+
const CACHE_TIME = 3600;
17+
18+
private array $tasks = array();
19+
private array $categories = array();
20+
21+
public function __construct(Login $login) {
22+
$this->loadAnswers($login->getGroup());
23+
}
24+
25+
private function loadAnswers(string $group) : void {
26+
$r = new JSONReader('cache_' . $group);
27+
if(
28+
$r->isValue(['name']) && $r->isValue(['category']) && $r->isValue(['time']) &&
29+
$r->getValue(['time']) + self::CACHE_TIME > time()
30+
){
31+
$this->tasks = $r->getValue(['name']);
32+
$this->categories = $r->getValue(['category']);
33+
}
34+
else{
35+
$data = $this->refreshCache($group);
36+
$data['time'] = time();
37+
38+
$this->tasks = $data['name'];
39+
$this->categories = $data['category'];
40+
41+
$r->setArray($data);
42+
}
43+
}
44+
45+
46+
private function refreshCache(string $group) : array {
47+
$stats = new TTTStats(['all'], API::getStorageDir($group));
48+
$combi = $stats->getAllResults()['combi'];
49+
50+
$data = array();
51+
foreach(array('name', 'category') as $col){
52+
$data[$col] = array();
53+
foreach(array_values(array_unique(array_column($combi, $col))) as $v){
54+
$data[$col][str_replace(['-', '_'], '', strtolower($v))] = $v;
55+
}
56+
}
57+
return $data;
58+
}
59+
60+
private function stripMultiple( string &$prefix ) : string {
61+
$pos = strrpos($prefix,',');
62+
if( $pos === false ){
63+
return "";
64+
}
65+
else{
66+
$static = substr($prefix, 0, $pos+1);
67+
$prefix = substr($prefix, $pos+1);
68+
return $static;
69+
}
70+
}
71+
72+
public function completeTask(string $prefix) : array {
73+
$static = $this->stripMultiple($prefix);
74+
return array_map( fn($s) => $static . $s, $this->getCompletes( $prefix, $this->tasks ) );
75+
}
76+
77+
public function completeCategory(string $prefix) : array {
78+
$static = $this->stripMultiple($prefix);
79+
return array_map( fn($s) => $static . $s, $this->getCompletes( $prefix, $this->categories ) );
80+
}
81+
82+
private function getCompletes( string $prefix, array $possibilities ) : array {
83+
$prefix = str_replace(['-', '_'], '', strtolower($prefix));
84+
$prefLen = strlen($prefix);
85+
86+
$answers = array();
87+
$sims = array();
88+
89+
$count = 0;
90+
foreach($possibilities as $search => $cand ){
91+
$percent = 0;
92+
if( $prefLen > 2 ){
93+
similar_text( $prefix, $search, $percent );
94+
if( $percent > 30 ){
95+
$sims[$cand] = $percent;
96+
}
97+
}
98+
if( substr($search, 0, $prefLen) == $prefix || $percent > 70 ){
99+
$answers[] = $cand;
100+
101+
$count++;
102+
if($count > 10){
103+
break;
104+
}
105+
}
106+
}
107+
if( $count < 10){
108+
arsort($sims, SORT_NUMERIC);
109+
$answers = array_unique(array_merge($answers, array_slice(array_keys($sims), 0, 10 - $count)));
110+
}
111+
return array_values($answers);
112+
}
113+
}
114+
?>

php/core/templates/edit_en.html

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,29 +56,23 @@ <h3>Add task</h3>
5656
<input type="hidden" id="datepickerEnd">
5757

5858
<script>
59-
var usedTasksCategories = localStorage.hasOwnProperty( 'usedTasksCategories' ) ?
60-
JSON.parse( localStorage.getItem( 'usedTasksCategories' ) ) : {
61-
"categories" : [],
62-
"tasks" : []
63-
};
6459
if(sessionStorage.hasOwnProperty( 'lastServerTask' )){
6560
var values = JSON.parse( sessionStorage.getItem( 'lastServerTask' ) );
6661
$.each(values, (k,v) => {
6762
$('input[name="'+ k +'"]').val(v);
6863
});
6964
}
7065
$( "input#category" ).autocomplete({
71-
source: usedTasksCategories.categories,
72-
minLength: 1
66+
source: "%%SERVERURL%%/ajax.php?type=category",
67+
minLength: 1,
68+
delay: 50
7369
});
7470
$( "input#task" ).autocomplete({
75-
source: usedTasksCategories.tasks,
76-
minLength: 1
71+
source: "%%SERVERURL%%/ajax.php?type=task",
72+
minLength: 1,
73+
delay: 50
7774
});
7875
$("form").on("submit", () => {
79-
usedTasksCategories.categories.push($( "input#category" ).val());
80-
usedTasksCategories.tasks.push($( "input#task" ).val());
81-
localStorage.setItem( 'usedTasksCategories', JSON.stringify(usedTasksCategories) );
8276
var values = {};
8377
$("input").each((k,v) => {
8478
values[$(v).attr("name")] = $(v).val();

php/core/templates/stats_en.html

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -72,55 +72,58 @@ <h3>Select data</h3>
7272
<input type="hidden" id="datepickerTo">
7373

7474
<script>
75-
$("select[name=time]").change(() => {
76-
if($("select[name=time]").val() == "range" ){
77-
$("div#rangeblock").removeClass("disable");
78-
}
79-
else {
80-
$("div#rangeblock").addClass("disable");
75+
$("select[name=time]").change(() => {
76+
if($("select[name=time]").val() == "range" ){
77+
$("div#rangeblock").removeClass("disable");
78+
}
79+
else {
80+
$("div#rangeblock").addClass("disable");
81+
}
82+
});
83+
$("form").on("submit", () => {
84+
var values = {};
85+
$("input, select").each((k,v) => {
86+
values[$(v).attr("name")] = {
87+
value : $(v).val(),
88+
tag : $(v).prop("tagName")
89+
};
90+
});
91+
localStorage.setItem( 'lastServerStats', JSON.stringify(values));
92+
});
93+
function dateDialog(element, destination){
94+
var pos = $(destination).offset();
95+
$( element ).datepicker(
96+
"dialog",
97+
$(destination).val(),
98+
function(v,o) {
99+
var m = o.selectedMonth+1;
100+
var d = o.selectedDay;
101+
$(destination).val(o.selectedYear +'-'+ (m <= 9 ? '0' : '') + m + '-' + (d <= 9 ? '0' : '') + d);
102+
},
103+
{
104+
dateFormat : "yy-mm-dd"
105+
},
106+
[pos.left, pos.top]
107+
);
81108
}
82-
});
83-
if(localStorage.hasOwnProperty( 'lastServerStats' )){
84-
var values = JSON.parse( localStorage.getItem( 'lastServerStats' ) );
85-
$.each(values, (k,v) => {
86-
$(v.tag + '[name="'+ k +'"]').val(v.value);
109+
$("#fromDialog").click( (e) => {
110+
e.preventDefault();
111+
dateDialog("input#datepickerFrom", "input[name=range-from]");
112+
});
113+
$("#toDialog").click( (e) => {
114+
e.preventDefault();
115+
dateDialog("input#datepickerTo", "input[name=range-to]");
87116
});
88-
$("select[name=time]").trigger('change');
89-
}
90-
$("form").on("submit", () => {
91-
var values = {};
92-
$("input, select").each((k,v) => {
93-
values[$(v).attr("name")] = {
94-
value : $(v).val(),
95-
tag : $(v).prop("tagName")
96-
};
117+
$( "input#names" ).autocomplete({
118+
source: "%%SERVERURL%%/ajax.php?type=task",
119+
minLength: 1,
120+
delay: 50
121+
});
122+
$( "input#cats" ).autocomplete({
123+
source: "%%SERVERURL%%/ajax.php?type=category",
124+
minLength: 1,
125+
delay: 50
97126
});
98-
localStorage.setItem( 'lastServerStats', JSON.stringify(values));
99-
});
100-
function dateDialog(element, destination){
101-
var pos = $(destination).offset();
102-
$( element ).datepicker(
103-
"dialog",
104-
$(destination).val(),
105-
function(v,o) {
106-
var m = o.selectedMonth+1;
107-
var d = o.selectedDay;
108-
$(destination).val(o.selectedYear +'-'+ (m <= 9 ? '0' : '') + m + '-' + (d <= 9 ? '0' : '') + d);
109-
},
110-
{
111-
dateFormat : "yy-mm-dd"
112-
},
113-
[pos.left, pos.top]
114-
);
115-
}
116-
$("#fromDialog").click( (e) => {
117-
e.preventDefault();
118-
dateDialog("input#datepickerFrom", "input[name=range-from]");
119-
});
120-
$("#toDialog").click( (e) => {
121-
e.preventDefault();
122-
dateDialog("input#datepickerTo", "input[name=range-to]");
123-
});
124127
</script>
125128

126129
<h3>Tables</h3>
@@ -180,4 +183,12 @@ <h3>Graph</h3>
180183
}
181184
});
182185
});
186+
187+
if(localStorage.hasOwnProperty( 'lastServerStats' )){
188+
var values = JSON.parse( localStorage.getItem( 'lastServerStats' ) );
189+
$.each(values, (k,v) => {
190+
$(v.tag + '[name="'+ k +'"]').val(v.value);
191+
});
192+
$("select[name=time]").trigger('change');
193+
}
183194
</script>

php/core/ttt/TTTStats.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
<?php
2+
/**
3+
* TaskTimeTerminate Sync-Server
4+
* https://github.com/KIMB-technologies/TaskTimeTerminate
5+
*
6+
* (c) 2020 KIMB-technologies
7+
* https://github.com/KIMB-technologies/
8+
*
9+
* released under the terms of GNU Public License Version 3
10+
* https://www.gnu.org/licenses/gpl-3.0.txt
11+
*/
12+
defined( 'TaskTimeTerminate' ) or die('Invalid Endpoint!');
13+
214
class TTTStats {
315

416
const DAYS_DISPLAY = 'd.m';

php/core/ttt/TTTStatsData.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
<?php
2+
/**
3+
* TaskTimeTerminate Sync-Server
4+
* https://github.com/KIMB-technologies/TaskTimeTerminate
5+
*
6+
* (c) 2020 KIMB-technologies
7+
* https://github.com/KIMB-technologies/
8+
*
9+
* released under the terms of GNU Public License Version 3
10+
* https://www.gnu.org/licenses/gpl-3.0.txt
11+
*/
12+
defined( 'TaskTimeTerminate' ) or die('Invalid Endpoint!');
13+
214
class TTTStatsData {
315

416
const FORWARD_TO_NOW = -1;

php/core/ttt/TTTTime.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
<?php
2+
/**
3+
* TaskTimeTerminate Sync-Server
4+
* https://github.com/KIMB-technologies/TaskTimeTerminate
5+
*
6+
* (c) 2020 KIMB-technologies
7+
* https://github.com/KIMB-technologies/
8+
*
9+
* released under the terms of GNU Public License Version 3
10+
* https://www.gnu.org/licenses/gpl-3.0.txt
11+
*/
12+
defined( 'TaskTimeTerminate' ) or die('Invalid Endpoint!');
13+
214
class TTTTime {
315

416
private const DEFAULT_FORMAT = 'dhm|s';

0 commit comments

Comments
 (0)