diff --git a/README.md b/README.md
index e69de29..7e35bf8 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,50 @@
+<<<<<<< HEAD
+# kvazar-network webapp
+Web-oriented content exploring platform for Kevacoin Blockchain
+
+### requirements
+```
+php-8^
+php-curl
+php-mbstring
+php-sqlite3
+php-pdo
+php-bcmath
+php-gd
+```
+#### database
+
+https://github.com/kvazar-network/database
+
+##### MySQL
+
+https://github.com/kvazar-network/webapp/tree/master
+
+##### SQLite
+
+https://github.com/kvazar-network/webapp/tree/sqlite
+
+#### crontab
+
+```
+0 0 * * * /path-to/php /path-to/crontab/sitemap.php > /dev/null 2>&1
+```
+
+### nginx sef_mode example
+
+```
+location / {
+ try_files $uri $uri/ =404 @sef;
+}
+
+location @sef {
+ rewrite ^(/.*)$ /?$1 last;
+}
+```
+
+### examples
+
+#### yggdrasil
+[http://[203:9fd0:95df:54d7:29db:5ee1:fe2d:95c7]](http://[203:9fd0:95df:54d7:29db:5ee1:fe2d:95c7])
+=======
+>>>>>>> master
diff --git a/config-default.php b/config-default.php
index a527d31..e6bb98d 100644
--- a/config-default.php
+++ b/config-default.php
@@ -6,14 +6,16 @@ ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
// Application
-define('BASE_URL', 'https://kvazar.today');
+define('BASE_URL', 'https://kvazar.today/');
define('PAGE_LIMIT', 10);
-define('SEF_MODE', true);
define('CACHE_ENABLED', false);
+define('TRENDS_ENABLED', false); // alpha
+define('TRENDS_SECONDS_OFFSET', 2592000);
+define('TRENDS_MIN_LENGHT', 4);
+define('TRENDS_LIMIT', 40);
+
// Database
-define('DB_HOST', 'localhost');
-define('DB_PORT', '3306');
-define('DB_NAME', '');
+define('DB_NAME', '../kvazar.sqlite');
define('DB_USERNAME', '');
define('DB_PASSWORD', '');
diff --git a/crontab/sitemap.php b/crontab/sitemap.php
index 5991e8b..5058d43 100644
--- a/crontab/sitemap.php
+++ b/crontab/sitemap.php
@@ -1,9 +1,9 @@
';
@@ -18,12 +18,12 @@ $transactions = [];
foreach ($db->getData(false, false, false, 0, 1000000) as $value) {
if (!in_array($value['namehash'], $namespaces)) {
- $namespace .= '' . BASE_URL . '/' . $value['namehash'] . '';
+ $namespace .= '' . BASE_URL . $value['namehash'] . '';
}
if (!in_array($value['namehash'], $transactions)) {
- $transaction .= '' . BASE_URL . '/' . $value['txid'] . '';
+ $transaction .= '' . BASE_URL . $value['txid'] . '';
}
$namespaces[] = $value['namehash'];
@@ -47,10 +47,10 @@ fclose($handle);
$sitemap = '';
$sitemap .= '';
$sitemap .= ' ';
-$sitemap .= ' ' . BASE_URL . '/sitemap.namespace.xml';
+$sitemap .= ' ' . BASE_URL . 'sitemap.namespace.xml';
$sitemap .= ' ';
$sitemap .= ' ';
-$sitemap .= ' ' . BASE_URL . '/sitemap.transaction.xml';
+$sitemap .= ' ' . BASE_URL . 'sitemap.transaction.xml';
$sitemap .= ' ';
$sitemap .= '';
diff --git a/library/icon.php b/library/icon.php
index 3daeddc..4df6a58 100755
--- a/library/icon.php
+++ b/library/icon.php
@@ -165,7 +165,7 @@ final class Icon {
for ($i = 0; $i < count($shape); $i++)
$shape[$i] = $shape[$i] * $this->_spriteZ;
- imagefilledpolygon($sprite, $shape, count($shape) / 2, $fg);
+ imagefilledpolygon($sprite, $shape, $fg);
for ($i = 0; $i < $rotation; $i++)
$sprite = imagerotate($sprite, 90, $bg);
@@ -215,7 +215,7 @@ final class Icon {
for ($i = 0; $i < count($shape); $i++)
$shape[$i] = $shape[$i] * $this->_spriteZ;
if (count($shape) > 0)
- imagefilledpolygon($sprite, $shape, count($shape) / 2, $fg);
+ imagefilledpolygon($sprite, $shape, $fg);
return $sprite;
}
diff --git a/library/sqlite.php b/library/sqlite.php
new file mode 100644
index 0000000..fa4aaf1
--- /dev/null
+++ b/library/sqlite.php
@@ -0,0 +1,268 @@
+_db = new PDO('sqlite:' . $database, $username, $password);
+ $this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $this->_db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
+ $this->_db->setAttribute(PDO::ATTR_TIMEOUT, 600);
+
+ $this->_db->query('
+ CREATE TABLE IF NOT EXISTS "namespace"(
+ "nameSpaceId" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nameSpaceId">=0),
+ "timeIndexed" INTEGER NOT NULL CHECK("timeIndexed">=0),
+ "hash" CHAR(34) NOT NULL,
+ CONSTRAINT "hash_UNIQUE"
+ UNIQUE("hash")
+ )
+ ');
+
+ $this->_db->query('
+ CREATE TABLE IF NOT EXISTS "block"(
+ "blockId" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("blockId">=0),
+ "timeIndexed" INTEGER NOT NULL CHECK("timeIndexed">=0),
+ "lostTransactions" INTEGER NOT NULL CHECK("lostTransactions">=0)
+ )
+ ');
+
+ $this->_db->query('
+ CREATE TABLE IF NOT EXISTS "data"(
+ "dataId" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("dataId">=0),
+ "nameSpaceId" INTEGER NOT NULL CHECK("nameSpaceId">=0),
+ "blockId" INTEGER NOT NULL CHECK("blockId">=0),
+ "time" INTEGER NOT NULL CHECK("time">=0),
+ "timeIndexed" INTEGER NOT NULL CHECK("timeIndexed">=0),
+ "size" INTEGER NOT NULL,
+ "ns" TEXT NOT NULL CHECK("ns" IN(\'0\', \'1\')),
+ "deleted" TEXT NOT NULL CHECK("deleted" IN(\'0\', \'1\')),
+ "txid" CHAR(64) NOT NULL,
+ "key" TEXT NOT NULL,
+ "value" TEXT NOT NULL,
+ CONSTRAINT "txid_UNIQUE"
+ UNIQUE("txid"),
+ CONSTRAINT "fk_data_namespace"
+ FOREIGN KEY("nameSpaceId")
+ REFERENCES "namespace"("nameSpaceId"),
+ CONSTRAINT "fk_data_block"
+ FOREIGN KEY("blockId")
+ REFERENCES "block"("blockId")
+ )
+
+ ');
+
+ $this->_db->query('CREATE INDEX IF NOT EXISTS "data.fk_data_namespase_idx" ON "data" ("nameSpaceId")');
+ $this->_db->query('CREATE INDEX IF NOT EXISTS "data.fk_data_block_idx" ON "data" ("blockId")');
+ $this->_db->query('CREATE INDEX IF NOT EXISTS "data.deleted_INDEX" ON "data" ("deleted")');
+ $this->_db->query('CREATE INDEX IF NOT EXISTS "data.ns_INDEX" ON "data" ("ns")');
+
+ } catch(PDOException $e) {
+ trigger_error($e->getMessage());
+ }
+ }
+
+ public function getNamespaceValueByNS(string $ns) {
+
+ try {
+
+ $query = $this->_db->prepare('SELECT `data`.`value` AS `value`
+
+ FROM `data`
+ JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`)
+
+ WHERE `namespace`.`hash` = ?
+ AND `data`.`ns` = "1"
+ -- AND `data`.`deleted` = "0" --
+
+ ORDER BY `data`.`blockId` DESC
+
+ LIMIT 1');
+
+ $query->execute([$ns]);
+
+ $result = $query->fetch();
+
+ return $result ? $result['value'] : '';
+
+ } catch(PDOException $e) {
+
+ trigger_error($e->getMessage());
+ return false;
+ }
+ }
+
+ public function getNamespaceHashByTX(string $txid) {
+
+ try {
+
+ $query = $this->_db->prepare('SELECT `namespace`.`hash`
+
+ FROM `namespace`
+ JOIN `data` ON (`data`.`nameSpaceId` = `namespace`.`nameSpaceId`)
+
+ WHERE `data`.`txid` = ?');
+
+ $query->execute([$txid]);
+
+ return $query->rowCount() ? $query->fetch()['hash'] : '';
+
+ } catch(PDOException $e) {
+
+ trigger_error($e->getMessage());
+ return false;
+ }
+ }
+
+ public function getData(string $namehash = '', string $txid = '', string $search = '', int $start = 0, int $limit = 10) {
+
+ try {
+
+ if ($txid) {
+
+ $query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`,
+ `namespace`.`hash` AS `namehash`,
+ `data`.`time` AS `time`,
+ `data`.`key` AS `key`,
+ `data`.`value` AS `value`,
+ `data`.`txid` AS `txid`
+
+ FROM `data`
+ JOIN `block` ON (`block`.`blockId` = `data`.`blockId`)
+ JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`)
+
+ WHERE `data`.`txid` = ?
+ AND `data`.`ns` = "0"
+ -- AND `data`.`deleted` = "0" --
+
+ ORDER BY `block`.`blockId` DESC
+
+ LIMIT ' . (int) $start . ',' . (int) $limit);
+
+ $query->execute([$txid]);
+
+ } else if ($namehash) {
+
+ $query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`,
+ `namespace`.`hash` AS `namehash`,
+ `data`.`time` AS `time`,
+ `data`.`key` AS `key`,
+ `data`.`value` AS `value`,
+ `data`.`txid` AS `txid`
+
+ FROM `data`
+ JOIN `block` ON (`block`.`blockId` = `data`.`blockId`)
+ JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`)
+
+ WHERE `namespace`.`hash` = ?
+ AND `data`.`ns` = "0"
+ -- AND `data`.`deleted` = "0" --
+
+ ORDER BY `block`.`blockId` DESC
+
+ LIMIT ' . (int) $start . ',' . (int) $limit);
+
+ $query->execute([$namehash]);
+
+ } else if ($search) {
+
+ $query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`,
+ `namespace`.`hash` AS `namehash`,
+ `data`.`time` AS `time`,
+ `data`.`key` AS `key`,
+ `data`.`value` AS `value`,
+ `data`.`txid` AS `txid`
+
+ FROM `data`
+ JOIN `block` ON (`block`.`blockId` = `data`.`blockId`)
+ JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`)
+
+ WHERE (`data`.`key` LIKE :search
+ OR `data`.`value` LIKE :search
+ OR `block`.`blockId` LIKE :search
+ OR `namespace`.`hash` LIKE :search
+ OR `data`.`txid` LIKE :search)
+
+ AND `data`.`ns` = "0"
+ -- AND `data`.`deleted` = "0" --
+
+ ORDER BY `block`.`blockId` DESC
+
+ LIMIT ' . (int) $start . ',' . (int) $limit);
+
+ $query->bindValue(':search', '%' . $search . '%', PDO::PARAM_STR);
+
+ $query->execute();
+
+ } else {
+
+ $query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`,
+ `namespace`.`hash` AS `namehash`,
+ `data`.`time` AS `time`,
+ `data`.`key` AS `key`,
+ `data`.`value` AS `value`,
+ `data`.`txid` AS `txid`
+
+ FROM `data`
+ JOIN `block` ON (`block`.`blockId` = `data`.`blockId`)
+ JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`)
+
+ WHERE `data`.`ns` = "0"
+ -- AND `data`.`deleted` = "0" --
+
+ ORDER BY `block`.`blockId` DESC
+
+ LIMIT ' . (int) $start . ',' . (int) $limit);
+
+ $query->execute();
+ }
+
+ $result = $query->fetchAll();
+
+ return $result ? $result : [];
+
+ } catch(PDOException $e) {
+
+ trigger_error($e->getMessage());
+ return false;
+ }
+ }
+
+ public function getTrends(int $offset = 0) {
+
+ try {
+
+ $query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`,
+ `namespace`.`hash` AS `namehash`,
+ `data`.`time` AS `time`,
+ `data`.`key` AS `key`,
+ `data`.`value` AS `value`,
+ `data`.`txid` AS `txid`
+
+ FROM `data`
+ JOIN `block` ON (`block`.`blockId` = `data`.`blockId`)
+ JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`)
+
+ WHERE `data`.`ns` = "0"
+ AND `data`.`time` >= ' . (int) $offset . '
+ -- AND `data`.`deleted` = "0" --
+
+ ORDER BY `block`.`blockId` DESC');
+
+ $query->execute();
+
+ $result = $query->fetchAll();
+
+ return $result ? $result : [];
+
+ } catch(PDOException $e) {
+
+ trigger_error($e->getMessage());
+ return false;
+ }
+ }
+}
diff --git a/public/css/app.css b/public/css/app.css
index 7ba85cf..f67d71b 100755
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -12,8 +12,8 @@ button::-moz-focus-inner {
input, button {
opacity: 0.8;
- color: #18102d;
- background: #BFBACC;
+ color: #000;
+ background: #ABA6B7;
border: 0;
border-radius: 3px;
height: 18px;
@@ -23,8 +23,8 @@ input, button {
}
body {
- color: #E8E8E8;
- background-color: #18102d;
+ color: #BFBACC;
+ background-color: #000;
font-family: Sans-Serif, Arial;
font-size: 14px;
font-weight: normal;
@@ -32,12 +32,7 @@ body {
}
a {
- color: #BFBACC;
- text-decoration: none;
-}
-
-a {
- color: #BFBACC;
+ color: #ABA6B7;
text-decoration: none;
-moz-transition: all .5s ease-in;
-o-transition: all .5s ease-in;
@@ -47,7 +42,7 @@ a {
}
a:hover {
- color: #E8E8E8;
+ color: #BFBACC;
-webkit-transition: all .5s ease-in; /* issue #2 */
}
@@ -96,7 +91,7 @@ img:hover {
.b-g::before {
content: "";
- background-image: linear-gradient(to left, #9B94BF, #18102d);
+ background-image: linear-gradient(to left, #9B94BF, #000);
height: 1px;
width: 50%;
max-width: 360px;
@@ -105,7 +100,7 @@ img:hover {
.b-g::after {
content: "";
- background-image: linear-gradient(to right, #9B94BF, #18102d);
+ background-image: linear-gradient(to right, #9B94BF, #000);
height: 1px;
width: 50%;
max-width: 360px;
@@ -127,7 +122,7 @@ img:hover {
.c-1:active,
.c-1:visited,
.c-1:hover {
- color: #ABA6B7;
+ color: #BFBACC;
}
.c-2,
diff --git a/public/index.php b/public/index.php
index e69de29..3970c11 100644
--- a/public/index.php
+++ b/public/index.php
@@ -0,0 +1,174 @@
+<<<<<<< HEAD
+ 0) {
+ $limit = PAGE_LIMIT * $page - PAGE_LIMIT;
+} else {
+ $limit = PAGE_LIMIT * $page;
+}
+
+$db = new SQLite(DB_NAME, DB_USERNAME, DB_PASSWORD);
+
+if ($ns) {
+
+ $namespaceHash = $ns;
+ $namespaceValue = $db->getNamespaceValueByNS($ns);
+
+} else if ($tx) {
+
+ $namespaceHash = $db->getNamespaceHashByTX($tx);
+ $namespaceValue = $db->getNamespaceValueByNS($namespaceHash);
+
+} else {
+
+ $namespaceHash = false;
+ $namespaceValue = false;
+}
+
+$trends = [];
+
+if (TRENDS_ENABLED) {
+
+ foreach ($db->getTrends(time() - TRENDS_SECONDS_OFFSET) as $value) {
+
+ foreach ((array) explode(' ', strip_tags(html_entity_decode(nl2br(trim($value['key']))))) as $trend) {
+
+ if (strlen($trend) >= TRENDS_MIN_LENGHT) {
+
+ $trend = strtolower($trend);
+
+ if (isset($trends[$trend])) {
+ $trends[$trend]++;
+ } else {
+ $trends[$trend] = 1;
+ }
+ }
+ }
+
+ foreach ((array) explode(' ', strip_tags(html_entity_decode(nl2br(trim($value['value']))))) as $trend) {
+
+ if (strlen($trend) >= TRENDS_MIN_LENGHT) {
+
+ $trend = strtolower($trend);
+
+ if (isset($trends[$trend])) {
+ $trends[$trend]++;
+ } else {
+ $trends[$trend] = 1;
+ }
+ }
+ }
+ }
+
+ arsort($trends);
+
+ $trends = array_slice($trends, 0, TRENDS_LIMIT);
+
+ $trends = array_flip($trends);
+}
+
+$data = [];
+foreach ($db->getData($ns, $tx, $query, $limit, PAGE_LIMIT) as $value) {
+ $data[] = [
+ 'namehash' => $value['namehash'],
+ 'block' => $value['block'],
+ 'txid' => $value['txid'],
+ 'time' => date(($rss ? 'r' : 'd-m-Y H:i'), $value['time']),
+ 'key' => $rss ? htmlentities(strip_tags(trim($value['key'])), ENT_XML1) : nl2br(trim($value['key'])),
+ 'value' => $rss ? htmlentities(strip_tags(trim($value['value'])), ENT_XML1): nl2br(trim($value['value'])),
+ ];
+}
+
+$older = false;
+$newer = false;
+
+if (!in_array($page, [0, 1])) {
+ if ($page == 2) {
+ $newer = ($ns ? $ns : '');
+ } else {
+ $newer = ($ns ? $ns . '/' . ($page - 1) : ($page - 1));
+ }
+
+ if ($query) {
+ $newer = $newer . '?q=' . $query;
+ }
+}
+
+if ($data) {
+ if (in_array($page, [0, 1])) {
+ $older = ($ns ? $ns . '/2' : '2');
+ } else {
+ $older = ($ns ? $ns . '/' . ($page + 1) : ($page + 1));
+ }
+
+ if ($query) {
+ $older = $older . '?q=' . $query;
+ }
+}
+
+if ($ns) {
+ if ($page) {
+ $hrefThisPage = $ns . '/' . $page;
+ } else {
+ $hrefThisPage = $ns;
+ }
+} else {
+ if ($page) {
+ $hrefThisPage = $page;
+ } else {
+ $hrefThisPage = '';
+ }
+}
+
+if ($rss) {
+
+ header('Content-type: application/xml');
+ require_once('rss.phtml');
+
+} else {
+
+ require_once('index.phtml');
+
+}
+=======
+>>>>>>> master
diff --git a/public/index.phtml b/public/index.phtml
index 0b80271..5bdd177 100755
--- a/public/index.phtml
+++ b/public/index.phtml
@@ -1,11 +1,11 @@
-
+
-
+
@@ -20,6 +20,8 @@
| | KVAZAR
+
+ KVAZAR | SEARCH |
KVAZAR | TODAY
@@ -29,11 +31,11 @@
-
+
@@ -42,24 +44,30 @@
+
+
+
+