diff --git a/.env.example b/.env.example
index 6c1a6bc..46bd24f 100644
--- a/.env.example
+++ b/.env.example
@@ -14,7 +14,7 @@ APP_AUTHOR="Daniel Brendel"
APP_CONTACT="dbrendel1988@gmail.com"
APP_TITLE="${APP_NAME} - Integrate Steam Widgets into your website"
APP_DESCRIPTION="Integrate Steam Widgets of your game/app into your website"
-APP_KEYWORDS="steam, widgets, steam widgets, steam game widget, steam app widget, steam server widget, steam player widget"
+APP_KEYWORDS="steam, widgets, steam widgets, steam game widget, steam app widget, steam server widget, steam player widget, steam group widget, steam workshop widget"
APP_DEBUG=true
APP_BASEDIR=""
APP_TIMEZONE=null
@@ -57,6 +57,10 @@ DB_DATABASE=asatru
DB_DRIVER=mysql
DB_CHARSET="utf8"
+# Caching
+CACHE_DRIVER=null
+CACHE_DURATION=512
+
# SMTP settings
SMTP_FROMNAME="Test"
SMTP_FROMADDRESS="test@domain.tld"
diff --git a/app/config/cache.php b/app/config/cache.php
new file mode 100644
index 0000000..d94e3ed
--- /dev/null
+++ b/app/config/cache.php
@@ -0,0 +1,6 @@
+ env('CACHE_DRIVER', null),
+ 'duration' => env('CACHE_DURATION', 123)
+];
\ No newline at end of file
diff --git a/app/controller/api.php b/app/controller/api.php
index bb4d6c0..c4ca2f4 100644
--- a/app/controller/api.php
+++ b/app/controller/api.php
@@ -26,7 +26,7 @@ class ApiController extends BaseController {
$appid = $request->params()->query('appid', null);
$language = $request->params()->query('lang', 'english');
- $data = SteamApp::querySteamData($appid, $language);
+ $data = SteamCache::cachedSteamApp($appid, $language);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_APP);
@@ -47,7 +47,7 @@ class ApiController extends BaseController {
try {
$addr = $request->params()->query('addr', null);
- $data = SteamServer::querySteamData(env('STEAM_API_KEY'), $addr);
+ $data = SteamCache::cachedSteamServer(env('STEAM_API_KEY'), $addr);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_SERVER);
@@ -68,7 +68,7 @@ class ApiController extends BaseController {
try {
$steamid = $request->params()->query('steamid', null);
- $data = SteamUser::querySteamData(env('STEAM_API_KEY'), $steamid);
+ $data = SteamCache::cachedSteamUser(env('STEAM_API_KEY'), $steamid);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_USER);
@@ -89,7 +89,7 @@ class ApiController extends BaseController {
try {
$itemid = $request->params()->query('itemid', null);
- $data = SteamWorkshop::querySteamData($itemid);
+ $data = SteamCache::cachedSteamWorkshop($itemid);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_WORKSHOP);
@@ -110,7 +110,7 @@ class ApiController extends BaseController {
try {
$group = $request->params()->query('group', null);
- $data = SteamGroup::querySteamData($group);
+ $data = SteamCache::cachedSteamGroup($group);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_GROUP);
diff --git a/app/migrations/CacheModel.php b/app/migrations/CacheModel.php
new file mode 100644
index 0000000..82d99bb
--- /dev/null
+++ b/app/migrations/CacheModel.php
@@ -0,0 +1,49 @@
+connection = $pdo;
+ }
+
+ /**
+ * Called when the table shall be created or modified
+ *
+ * @return void
+ */
+ public function up()
+ {
+ $this->database = new Asatru\Database\Migration('CacheModel', $this->connection);
+ $this->database->drop();
+ $this->database->add('id INT NOT NULL AUTO_INCREMENT PRIMARY KEY');
+ $this->database->add('ident VARCHAR(260) NOT NULL');
+ $this->database->add('value BLOB NULL');
+ $this->database->add('updated_at TIMESTAMP');
+ $this->database->add('created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP');
+ $this->database->create();
+ }
+
+ /**
+ * Called when the table shall be dropped
+ *
+ * @return void
+ */
+ public function down()
+ {
+ $this->database = new Asatru\Database\Migration('Cache', $this->connection);
+ $this->database->drop();
+ }
+}
\ No newline at end of file
diff --git a/app/migrations/migrations.list b/app/migrations/migrations.list
index 63538ff..5ec79b3 100644
--- a/app/migrations/migrations.list
+++ b/app/migrations/migrations.list
@@ -1 +1,4 @@
47f3d3306fbd25715600db55b33b1542293ab5eb593205d6f5884bcaafa5d9a4627c76af04b684962c99a9518ef6b3d10e983203f6b5a8576912445d8f285fb7
+
+cd19e5ec4a12d40d8d3ecdf267ef890e80fdd94ab28f81fddeb0c12b6f6b88773157e469c2d693abd4583e18b9b5a126c3fcecd6c07f4374c6c6e2837166b2ec
+
diff --git a/app/models/CacheModel.php b/app/models/CacheModel.php
new file mode 100644
index 0000000..6214010
--- /dev/null
+++ b/app/models/CacheModel.php
@@ -0,0 +1,206 @@
+count() == 0) {
+ $value = $closure();
+
+ $data = array(
+ 'ident' => $ident,
+ 'value' => $value,
+ 'updated_at' => date('Y-m-d H:i:s')
+ );
+
+ foreach ($data as $key => $val) {
+ CacheModel::insert($key, $val);
+ }
+
+ CacheModel::go();
+
+ return $value;
+ } else {
+ $data = $item->get(0);
+ $dtLast = new DateTime(date('Y-m-d H:i:s', strtotime($data->get('updated_at'))));
+ $dtLast->add(new DateInterval('PT' . $timeInSeconds . 'S'));
+ $dtNow = new DateTime('now');
+
+ if ($dtNow < $dtLast) {
+ return $data->get('value');
+ } else {
+ $value = $closure();
+
+ $updData = array(
+ 'value' => $value,
+ 'updated_at' => date('Y-m-d H:i:s')
+ );
+
+ foreach ($updData as $key => $val) {
+ CacheModel::update($key, $val);
+ }
+
+ CacheModel::where('id', '=', $data->get('id'));
+
+ CacheModel::go();
+
+ return $value;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Query an entire item
+ *
+ * @param $ident
+ * @param $default
+ * @return mixed
+ */
+ public static function query($ident, $default = null)
+ {
+ $what = null;
+ if (strpos($ident, '.') !== false) {
+ $what = explode('.', $ident);
+ }
+
+ $result = CacheModel::where('ident', '=', (((is_array($what)) && (count($what) > 0)) ? $what[0] : $ident))->first();
+ if (!$result) {
+ return $default;
+ }
+
+ if ((is_array($what)) && (count($what) > 1)) {
+ return $result->get($what[1]);
+ }
+
+ return $result->get('value');
+ }
+
+ /**
+ * Check for item existence
+ *
+ * @param $ident
+ * @return bool
+ */
+ public static function has($ident)
+ {
+ $item = CacheModel::find($ident, 'ident');
+ if ($item->count() > 0) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if item cache time is elapsed
+ *
+ * @param $ident
+ * @param $timeInSeconds
+ * @return bool
+ */
+ public static function elapsed($ident, $timeInSeconds)
+ {
+ if (!CacheModel::has($ident)) {
+ return false;
+ }
+
+ $data = CacheModel::where('ident', '=', $ident)->first();
+
+ $dtLast = new DateTime(date('Y-m-d H:i:s', strtotime($data->get('updated_at'))));
+ $dtLast->add(new DateInterval('PT' . $timeInSeconds . 'S'));
+ $dtNow = new DateTime('now');
+
+ return ($dtNow >= $dtLast);
+ }
+
+ /**
+ * Get item and then delete it
+ *
+ * @param $ident
+ * @return mixed
+ */
+ public static function pull($ident)
+ {
+ $item = CacheModel::find($ident, 'ident');
+ if ($item->count() > 0) {
+ $data = $item->get(0);
+
+ CacheModel::where('id', '=', $item->get(0)->get('id'))->delete();
+
+ return $data->get('value');
+ }
+
+ return null;
+ }
+
+ /**
+ * Write item to table
+ *
+ * @param $ident
+ * @param $value
+ * @return bool
+ */
+ public static function put($ident, $value)
+ {
+ if (CacheModel::has($ident)) {
+ return false;
+ }
+
+ $data = array(
+ 'ident' => $ident,
+ 'value' => $value,
+ 'updated_at' => date('Y-m-d H:i:s')
+ );
+
+ foreach ($data as $key => $val) {
+ CacheModel::insert($key, $val);
+ }
+
+ CacheModel::go();
+
+ return true;
+ }
+
+ /**
+ * Forget cache item
+ *
+ * @param string $ident The item identifier
+ * @return bool
+ */
+ public static function forget($ident)
+ {
+ $item = CacheModel::find($ident, 'ident');
+ if ($item->count() > 0) {
+ CacheModel::where('id', '=', $item->get(0)->get('id'))->delete();
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Return the associated table name of the migration
+ *
+ * @return string
+ */
+ public static function tableName()
+ {
+ return 'CacheModel';
+ }
+}
+
\ No newline at end of file
diff --git a/app/modules/SteamCache.php b/app/modules/SteamCache.php
new file mode 100644
index 0000000..2b995c7
--- /dev/null
+++ b/app/modules/SteamCache.php
@@ -0,0 +1,106 @@
+driver === 'db') {
+ return json_decode(CacheModel::remember('steam_app_' . $appid . '_' . $lang, $cache->duration, function() use ($appid, $lang) {
+ return json_encode(SteamApp::querySteamData($appid, $lang));
+ }));
+ } else if ($cache->driver === 'redis') {
+ throw new \Exception('Not implemented yet.');
+ } else {
+ return SteamApp::querySteamData($appid, $lang);
+ }
+ }
+
+ /**
+ * @param $key
+ * @param $steamid
+ * @return mixed
+ */
+ public static function cachedSteamUser($key, $steamid)
+ {
+ $cache = config('cache');
+
+ if ($cache->driver === 'db') {
+ return json_decode(CacheModel::remember('steam_user_' . $steamid, $cache->duration, function() use ($key, $steamid) {
+ return json_encode(SteamUser::querySteamData($key, $steamid));
+ }));
+ } else if ($cache->driver === 'redis') {
+ throw new \Exception('Not implemented yet.');
+ } else {
+ return SteamUser::querySteamData($key, $steamid);
+ }
+ }
+
+ /**
+ * @param $itemid
+ * @return mixed
+ */
+ public static function cachedSteamWorkshop($itemid)
+ {
+ $cache = config('cache');
+
+ if ($cache->driver === 'db') {
+ return json_decode(CacheModel::remember('steam_workshop_' . $itemid, $cache->duration, function() use ($itemid) {
+ return json_encode(SteamWorkshop::querySteamData($itemid));
+ }));
+ } else if ($cache->driver === 'redis') {
+ throw new \Exception('Not implemented yet.');
+ } else {
+ return SteamWorkshop::querySteamData($itemid);
+ }
+ }
+
+ /**
+ * @param $group
+ * @return mixed
+ */
+ public static function cachedSteamGroup($group)
+ {
+ $cache = config('cache');
+
+ if ($cache->driver === 'db') {
+ return json_decode(CacheModel::remember('steam_group_' . $group, $cache->duration, function() use ($group) {
+ return json_encode(SteamGroup::querySteamData($group));
+ }));
+ } else if ($cache->driver === 'redis') {
+ throw new \Exception('Not implemented yet.');
+ } else {
+ return SteamGroup::querySteamData($group);
+ }
+ }
+
+ /**
+ * @param $key
+ * @param $addr
+ * @return mixed
+ */
+ public static function cachedSteamServer($key, $addr)
+ {
+ $cache = config('cache');
+
+ if ($cache->driver === 'db') {
+ return json_decode(CacheModel::remember('steam_server_' . $addr, $cache->duration, function() use ($key, $addr) {
+ return json_encode(SteamServer::querySteamData($key, $addr));
+ }));
+ } else if ($cache->driver === 'redis') {
+ throw new \Exception('Not implemented yet.');
+ } else {
+ return SteamServer::querySteamData($key, $addr);
+ }
+ }
+}
diff --git a/app/resources/sass/app.scss b/app/resources/sass/app.scss
index 62803ca..18d2363 100644
--- a/app/resources/sass/app.scss
+++ b/app/resources/sass/app.scss
@@ -97,6 +97,12 @@ a.navbar-burger:hover {
height: 100%;
}
+.header-centered {
+ @media screen and (min-width: 1089px) {
+ transform: translateX(9.5%);
+ }
+}
+
.header-content {
position: relative;
top: 50%;
diff --git a/app/views/doc.php b/app/views/doc.php
index a9fd0bb..d96a249 100644
--- a/app/views/doc.php
+++ b/app/views/doc.php
@@ -653,7 +653,7 @@ document.addEventListener('DOMContentLoaded', function() {
- This renders the following widget:
+ This renders the following widget: