You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-13 22:12:50 +02:00
more changes
This commit is contained in:
@@ -113,24 +113,8 @@ abstract class ApiController extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
static private function serializeResponse($data) {
|
||||
$output = $data;
|
||||
|
||||
if ($output instanceof Collection) $output = $output->all();
|
||||
|
||||
if ($output instanceof BaseModel) {
|
||||
$output = $output->toPublicArray();
|
||||
} else if (is_array($output)) {
|
||||
foreach ($output as $k => $v) {
|
||||
$output[$k] = self::serializeResponse($v);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
static protected function successResponse($data = null) {
|
||||
$output = self::serializeResponse($data);
|
||||
$output = BaseModel::anythingToPublicArray($data);
|
||||
return new JsonResponse($output);
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,7 @@ namespace AppBundle\Model;
|
||||
|
||||
use \Illuminate\Database\Eloquent\Model;
|
||||
use \Illuminate\Support\Facades\DB;
|
||||
use \Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class BaseModel extends \Illuminate\Database\Eloquent\Model {
|
||||
|
||||
@@ -39,6 +40,92 @@ class BaseModel extends \Illuminate\Database\Eloquent\Model {
|
||||
return self::$clientId;
|
||||
}
|
||||
|
||||
static public function anythingToAsciiTable($data, $fields = null) {
|
||||
$data = self::anythingToPublicArray($data);
|
||||
if (!count($data)) return '';
|
||||
$header = array();
|
||||
$r = $data[0];
|
||||
foreach ($r as $k => $v) {
|
||||
$header[] = $k;
|
||||
}
|
||||
|
||||
$lengths = array();
|
||||
foreach ($header as $f) {
|
||||
$lengths[$f] = max(strlen($f), self::fieldMaxLength($f, $data));
|
||||
}
|
||||
|
||||
if (!$fields) {
|
||||
$fields = $header;
|
||||
} else {
|
||||
$header = $fields;
|
||||
}
|
||||
|
||||
$rows = array();
|
||||
|
||||
$dividers = array();
|
||||
$row = array();
|
||||
foreach ($header as $k) {
|
||||
$row[] = str_pad($k, $lengths[$k]);
|
||||
}
|
||||
$rows[] = $row;
|
||||
$dividers[] = ' | ';
|
||||
|
||||
$row = array();
|
||||
foreach ($header as $k) {
|
||||
$row[] = str_repeat('-', $lengths[$k]);
|
||||
}
|
||||
$rows[] = $row;
|
||||
$dividers[] = '-|-';
|
||||
|
||||
foreach ($data as $r) {
|
||||
$row = array();
|
||||
foreach ($r as $k => $v) {
|
||||
if (!in_array($k, $fields)) continue;
|
||||
$row[$k] = str_pad($v, $lengths[$k]);
|
||||
}
|
||||
$rows[] = $row;
|
||||
$dividers[] = ' | ';
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$output = '';
|
||||
foreach ($rows as $row) {
|
||||
$line = '';
|
||||
foreach ($row as $v) {
|
||||
if ($line != '') $line .= $dividers[$i];
|
||||
$line .= $v;
|
||||
}
|
||||
$output .= $line . "\n";
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
static private function fieldMaxLength($field, $data) {
|
||||
$s = 0;
|
||||
foreach ($data as $row) {
|
||||
$s = max(strlen($row[$field]), $s);
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
static public function anythingToPublicArray($data) {
|
||||
$output = $data;
|
||||
|
||||
if ($output instanceof Collection) $output = $output->all();
|
||||
|
||||
if ($output instanceof BaseModel) {
|
||||
$output = $output->toPublicArray();
|
||||
} else if (is_array($output)) {
|
||||
foreach ($output as $k => $v) {
|
||||
$output[$k] = self::anythingToPublicArray($v);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function fromPublicArray($array) {
|
||||
foreach ($array as $k => $v) {
|
||||
if ($k == 'rev_id') {
|
||||
|
@@ -11,19 +11,58 @@ class Change extends BaseModel {
|
||||
);
|
||||
|
||||
static public function changesDoneAfterId($userId, $clientId, $changeId) {
|
||||
// Simplification:
|
||||
//
|
||||
// - If create, update, delete => return nothing
|
||||
// - If create, update => return last, and set type as 'create'
|
||||
// - If update, update, delete, update => return 'delete' only
|
||||
// - If update, update, update => return last
|
||||
|
||||
$limit = 100;
|
||||
$items = self::where('id', '>', $changeId)
|
||||
$changes = self::where('id', '>', $changeId)
|
||||
->where('user_id', '=', $userId)
|
||||
->where('client_id', '!=', $clientId)
|
||||
->orderBy('id')
|
||||
->limit($limit + 1)
|
||||
->get();
|
||||
$hasMore = $limit < count($items);
|
||||
if ($hasMore) array_pop($items);
|
||||
|
||||
$hasMore = $limit < count($changes);
|
||||
if ($hasMore) array_pop($changes);
|
||||
|
||||
$itemIdToChange = array();
|
||||
$createdItems = array();
|
||||
$deletedItems = array();
|
||||
foreach ($changes as $change) {
|
||||
if ($change->type == Change::enumId('type', 'create')) {
|
||||
$createdItems[] = $change->item_id;
|
||||
} else if ($change->type == Change::enumId('type', 'delete')) {
|
||||
$deletedItems[] = $change->item_id;
|
||||
}
|
||||
|
||||
$itemIdToChange[$change->item_id] = $change;
|
||||
}
|
||||
|
||||
$output = array();
|
||||
foreach ($itemIdToChange as $itemId => $change) {
|
||||
if (in_array($itemId, $createdItems) && in_array($itemId, $deletedItems)) {
|
||||
// Item both created then deleted - skip
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($itemId, $deletedItems)) {
|
||||
// Item was deleted at some point - just return one 'delete' event
|
||||
$change->type = Change::enumId('type', 'delete');
|
||||
} else if (in_array($itemId, $createdItems)) {
|
||||
// Item was created then updated - just return one 'create' event with the latest changes
|
||||
$change->type = Change::enumId('type', 'create');
|
||||
}
|
||||
|
||||
$output[] = $change;
|
||||
}
|
||||
|
||||
return array(
|
||||
'has_more' => $hasMore,
|
||||
'items' => $items,
|
||||
'items' => $output,
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -26,8 +26,12 @@ class BaseTestCase extends TestCase {
|
||||
return $this->createModelId('client', $num);
|
||||
}
|
||||
|
||||
protected function userId($num = 1) {
|
||||
return $this->createModelId('user', $num);
|
||||
}
|
||||
|
||||
protected function user($num = 1) {
|
||||
$id = $this->createModelId('user', $num);
|
||||
$id = $this->userId($num);
|
||||
$user = User::find($id);
|
||||
if ($user) return $user;
|
||||
|
||||
|
@@ -128,5 +128,44 @@ class ChangeTest extends BaseTestCase {
|
||||
$d = $n->toPublicArray();
|
||||
$this->assertEquals(2, $d['rev_id']);
|
||||
}
|
||||
|
||||
public function testListChanges() {
|
||||
$n1 = new Note();
|
||||
$n1->fromPublicArray(array('body' => 'test'));
|
||||
$n1->owner_id = $this->userId();
|
||||
$n1->save();
|
||||
|
||||
$n1->fromPublicArray(array('body' => 'test change'));
|
||||
$n1->save();
|
||||
|
||||
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(1), 0);
|
||||
|
||||
$this->assertCount(2, $r);
|
||||
$this->assertFalse($r['has_more']);
|
||||
$this->assertCount(0, $r['items']); // Since client 1 is the one that made the changes, no sync data needs to be returned
|
||||
|
||||
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(2), 0);
|
||||
|
||||
$this->assertCount(1, $r['items']);
|
||||
|
||||
$n2 = new Note();
|
||||
$n2->fromPublicArray(array('body' => 'second note'));
|
||||
$n2->owner_id = $this->userId();
|
||||
$n2->save();
|
||||
|
||||
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(2), 0);
|
||||
|
||||
$this->assertCount(2, $r['items']);
|
||||
|
||||
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(2), $r['items'][0]['id']);
|
||||
|
||||
$this->assertCount(1, $r['items']);
|
||||
|
||||
$n1->delete();
|
||||
|
||||
$r = Change::changesDoneAfterId($this->userId(), $this->clientId(2), 0);
|
||||
|
||||
$this->assertCount(1, $r['items']);
|
||||
}
|
||||
|
||||
}
|
@@ -16,7 +16,7 @@ $capsule = new \Illuminate\Database\Capsule\Manager();
|
||||
$capsule->addConnection([
|
||||
'driver' => 'mysql',
|
||||
'host' => 'localhost',
|
||||
'database' => 'notes_test',
|
||||
'database' => $dbName,
|
||||
'username' => 'root',
|
||||
'password' => 'pass',
|
||||
'charset' => 'utf8',
|
||||
|
Reference in New Issue
Block a user