diff --git a/src/Classes/MySQLDB.php b/src/Classes/MySQLDB.php
new file mode 100644
index 0000000..b55a7e2
--- /dev/null
+++ b/src/Classes/MySQLDB.php
@@ -0,0 +1,24 @@
+fetch_all(MYSQLI_ASSOC);
+
+ if($indexes != null)
+ $arr = array_index($arr, $indexes);
+
+ return $arr;
+ }
+
+}
\ No newline at end of file
diff --git a/src/Console/Commands/ScheduledTaskRun.php b/src/Console/Commands/ScheduledTaskRun.php
index 01e2c9e..cb080d0 100644
--- a/src/Console/Commands/ScheduledTaskRun.php
+++ b/src/Console/Commands/ScheduledTaskRun.php
@@ -3,12 +3,8 @@
namespace Andiwijaya\AppCore\Console\Commands;
use Andiwijaya\AppCore\Models\ScheduledTask;
-use Andiwijaya\AppCore\Models\ScheduledTaskInstance;
-use Carbon\Carbon;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
-use Symfony\Component\Process\Process;
class ScheduledTaskRun extends Command
{
diff --git a/src/Http/Controllers/ActionableController.php b/src/Http/Controllers/ActionableController.php
index 2f565ec..b88289a 100644
--- a/src/Http/Controllers/ActionableController.php
+++ b/src/Http/Controllers/ActionableController.php
@@ -30,7 +30,7 @@ public function store(Request $request){
return call_user_func_array([ $this, $method ], func_get_args());
}
- public function show(Request $request){
+ public function show(Request $request, $id){
$this->request = $request;
@@ -40,6 +40,16 @@ public function show(Request $request){
return call_user_func_array([ $this, $method ], func_get_args());
}
+ public function patch(Request $request){
+
+ $this->request = $request;
+
+ $action = isset(($actions = explode('|', $request->input('action', 'patch')))[0]) ? $actions[0] : '';
+ $method = action2method($action);
+ if(method_exists($this, $method))
+ return call_user_func_array([ $this, $method ], func_get_args());
+ }
+
public function onlyMethods($methods){
$arr = is_scalar($methods) ? [ $methods ] : (!is_array($methods) ? [] : $methods);
diff --git a/src/Http/Controllers/ListPageController2.php b/src/Http/Controllers/ListPageController2.php
index 2c8d0f9..2a67cfb 100644
--- a/src/Http/Controllers/ListPageController2.php
+++ b/src/Http/Controllers/ListPageController2.php
@@ -7,13 +7,13 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
-use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
+use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Str;
-class ListPageController2 extends BaseController{
+class ListPageController2 extends ActionableController{
public $model = null;
@@ -49,24 +49,6 @@ public function __construct()
View::share('meta', $this->meta);
}
- public function index(Request $request){
-
- $action = isset(($actions = explode('|', $request->get('action', 'fetch')))[0]) ? $actions[0] : '';
-
- $method = action2method($action);
- if(method_exists($this, $method))
- return call_user_func_array([ $this, $method ], func_get_args());
- }
-
- public function store(Request $request){
-
- $action = isset(($actions = explode('|', $request->get('action', 'save')))[0]) ? $actions[0] : '';
-
- $method = action2method($action);
- if(method_exists($this, $method))
- return call_user_func_array([ $this, $method ], func_get_args());
- }
-
public function applySorts($builder, array $sorts)
{
foreach($sorts as $sort){
diff --git a/src/Interfaces/VerboseOutputInterface.php b/src/Interfaces/VerboseOutputInterface.php
new file mode 100644
index 0000000..eb9bbdc
--- /dev/null
+++ b/src/Interfaces/VerboseOutputInterface.php
@@ -0,0 +1,9 @@
+extra['offline_message_at'] ?? null)));
$offline = self::isOffline();
+
if($offline && config('chat.offline-message') && $offline_message_at->diffInHours() > 2){
+ $message = config('chat.offline-message');
+ $faqs = config('chat.offline-message-faqs', []);
+ if(count($faqs) > 0){
+ $message .= "
Apakah yang anda cari terdapat dibawah ini: ";
+ foreach($faqs as $faq_topic){
+
+ $faq = FAQ::where('topic', $faq_topic)->first();
+ $message .= "seo_url}' target='_blank'>{$faq->topic} ";
+ }
+ $message .= " ";
+ }
+
$message = new ChatMessage([
'discussion_id'=>$discussion_id,
'direction'=>ChatMessage::DIRECTION_OUT,
- 'text'=>config('chat.offline-message'),
+ 'text'=>$message,
'is_system'=>1,
'extra'=>[ 'name'=>'Tara', 'avatar_url'=>'chat-figure.png' ],
]);
diff --git a/src/Models/ScheduledTask.php b/src/Models/ScheduledTask.php
index 1286aed..16f5578 100644
--- a/src/Models/ScheduledTask.php
+++ b/src/Models/ScheduledTask.php
@@ -4,11 +4,14 @@
use Andiwijaya\AppCore\Models\Traits\FilterableTrait;
use Andiwijaya\AppCore\Models\Traits\LoggedTraitV3;
+use Andiwijaya\AppCore\Providers\ScheduledTaskSecurityProvider;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Queue\SerializableClosure;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Str;
use Symfony\Component\Process\Process;
class ScheduledTask extends Model
@@ -60,28 +63,31 @@ public function results(){
public function preSave()
{
- if(in_array(($name = explode(':', explode(' ', $this->command)[0])[0]), [
- 'app',
- 'migrate',
- 'make',
- 'event',
- 'config',
- 'data',
- 'cache',
- 'list',
- 'optimize',
- 'down',
- 'up',
- 'clear-compiled',
- 'dump-server',
- 'db',
- 'queue',
- 'redis',
- 'route',
- 'schedule',
- 'vendor'
- ]))
- exc('Unable to use this command');
+ if(is_string($this->command)){
+
+ if(in_array(($name = explode(':', explode(' ', $this->command)[0])[0]), [
+ 'app',
+ 'migrate',
+ 'make',
+ 'event',
+ 'config',
+ 'data',
+ 'cache',
+ 'list',
+ 'optimize',
+ 'down',
+ 'up',
+ 'clear-compiled',
+ 'dump-server',
+ 'db',
+ 'queue',
+ 'redis',
+ 'route',
+ 'schedule',
+ 'vendor'
+ ]))
+ exc('Unable to use this command');
+ }
}
@@ -112,33 +118,60 @@ public function run(){
$this->status = self::STATUS_RUNNING;
$this->save();
- $report = $this->results()->create([
+ $result = $this->results()->create([
'status'=>self::STATUS_RUNNING,
'started_at'=>Carbon::now()->format('Y-m-d H:i:s'),
'pid'=>getmypid()
]);
- $exitCode = Artisan::call($this->command);
- $output = Artisan::output();
+ if(strpos($this->command, 'SerializableClosure') !== false){
- $report->status = $exitCode > 0 ? self::STATUS_ERROR : self::STATUS_COMPLETED;
- $report->verbose = $output;
- $report->ellapsed = microtime(1) - $t1;
- $report->completed_at = Carbon::now()->format('Y-m-d H:i:s');
- $report->save();
+ if (null !== $securityProvider = SerializableClosure::getSecurityProvider()) {
+ SerializableClosure::removeSecurityProvider();
+ }
- $this->status = $report->status;
- $this->save();
+ $command = unserialize($this->command)->getClosure();
+
+ if ($securityProvider !== null) {
+ SerializableClosure::addSecurityProvider($securityProvider);
+ }
+
+ try{
+ $output = call_user_func_array($command, [ $result ]);
+ $exitCode = 0;
+ }
+ catch(\Exception $ex){
+ $exitCode = 1;
+ $output = $ex->getMessage() . "@" . $ex->getFile() . ":" . $ex->getLine();
+ }
+ }
+ else{
+ $exitCode = Artisan::call($this->command);
+ $output = Artisan::output();
+ }
if($this->remove_after_completed)
$this->delete();
+ else{
+ $result->status = $exitCode > 0 ? self::STATUS_ERROR : self::STATUS_COMPLETED;
+ $result->verbose .= $output . PHP_EOL;
+ $result->ellapsed = microtime(1) - $t1;
+ $result->completed_at = Carbon::now()->format('Y-m-d H:i:s');
+ $result->save();
+
+ $this->status = $result->status;
+
+ $this->save();
+ }
}
public function runInBackground(){
chdir(base_path());
- exec("php artisan scheduled-task:run --id={$this->id} > /dev/null 2>&1 &", $output, $return_var);
+ $log_path = storage_path('logs/laravel.log');
+
+ exec("php artisan scheduled-task:run --id={$this->id} > {$log_path} 2>&1 &", $output, $return_var);
}
public static function check(Command $cmd = null){
@@ -216,103 +249,36 @@ public static function runOnceThenRemove(array $params, Command $cmd = null){
return $task;
}
- public function createInstances(){
-
- if($this->status != self::STATUS_ACTIVE) return;
-
- //\Illuminate\Support\Facades\Log::info("create instance: {$this->id}");
-
- switch($this->repeat){
-
- case self::REPEAT_NONE:
- if(count($this->instances) <= 0){
- $this->instances()->create([
- 'command'=>$this->command,
- 'start'=>$this->start
- ]);
- }
- break;
-
- case self::REPEAT_MINUTELY:
- if($this->instances->where('status', ScheduledTaskInstance::STATUS_SCHEDULED)->count() <= 0){
+ public static function runOnce($command, $description = ''){
- $instances = [];
- for($i = 1 ; $i <= 10 ; $i++){
- $instances[] = new ScheduledTaskInstance([
- 'command'=>$this->command,
- 'start'=>Carbon::now()->addMinutes($i)->format('Y-m-d H:i:00')
- ]);
- }
- $this->instances()->saveMany($instances);
- }
- break;
-
- case self::REPEAT_EVERY_FIVE_MINUTE:
- if($this->instances->where('status', ScheduledTaskInstance::STATUS_SCHEDULED)->count() <= 0){
-
- $instances = [];
- $currentMinute = Carbon::now()->minute;
- $addMinute = ((floor($currentMinute / 5) * 5) + 5) - $currentMinute;
- for($i = 1 ; $i <= 10 ; $i++){
- $instances[] = new ScheduledTaskInstance([
- 'command'=>$this->command,
- 'start'=>Carbon::now()->addMinutes($addMinute)->format('Y-m-d H:i:00')
- ]);
- $addMinute += 5;
- }
+ if($command instanceof \Closure){
- $this->instances()->saveMany($instances);
- }
- break;
-
- case self::REPEAT_EVERY_TEN_MINUTE:
- if($this->instances->where('status', ScheduledTaskInstance::STATUS_SCHEDULED)->count() <= 0){
-
- $instances = [];
- $currentMinute = Carbon::now()->minute;
- $addMinute = ((floor($currentMinute / 10) * 10) + 10) - $currentMinute;
- for($i = 1 ; $i <= 10 ; $i++){
- $instances[] = new ScheduledTaskInstance([
- 'command'=>$this->command,
- 'start'=>Carbon::now()->addMinutes($addMinute)->format('Y-m-d H:i:00')
- ]);
- $addMinute += 10;
- }
+ if (null !== $securityProvider = SerializableClosure::getSecurityProvider()) {
+ SerializableClosure::removeSecurityProvider();
+ }
- $this->instances()->saveMany($instances);
- }
- break;
+ $command = serialize(new SerializableClosure($command));
- case self::REPEAT_HOURLY:
- if($this->instances->where('status', ScheduledTaskInstance::STATUS_SCHEDULED)->count() <= 0){
+ if ($securityProvider !== null) {
+ SerializableClosure::addSecurityProvider($securityProvider);
+ }
+ }
- $instances = [];
- for($i = 1 ; $i <= 10 ; $i++){
- $instances[] = new ScheduledTaskInstance([
- 'command'=>$this->command,
- 'start'=>Carbon::now()->addHours($i)->format('Y-m-d H:00:00')
- ]);
- }
- $this->instances()->saveMany($instances);
- }
- break;
+ if(!$description)
+ $description = "Scheduled task - " . Str::random(5);
- case self::REPEAT_DAILY:
- if($this->instances->where('status', ScheduledTaskInstance::STATUS_SCHEDULED)->count() <= 0){
+ $task = new ScheduledTask([
+ 'command'=>$command,
+ 'description'=>$description,
+ 'repeat'=>self::REPEAT_NONE,
+ 'remove_after_completed'=>0
+ ]);
- $instances = [];
- for($i = 1 ; $i <= 10 ; $i++){
- $instances[] = new ScheduledTaskInstance([
- 'command'=>$this->command,
- 'start'=>Carbon::now()->addDays($i)->format('Y-m-d 00:00:00')
- ]);
- }
- $this->instances()->saveMany($instances);
- }
- break;
+ $task->save();
- }
+ $task->runInBackground();
+ return $task;
}
diff --git a/src/Models/ScheduledTaskInstance.php b/src/Models/ScheduledTaskInstance.php
deleted file mode 100644
index 0d36052..0000000
--- a/src/Models/ScheduledTaskInstance.php
+++ /dev/null
@@ -1,112 +0,0 @@
-self::STATUS_SCHEDULED
- ];
-
- protected $casts = [
- 'result_details'=>'array',
- 'completed_at'=>'datetime'
- ];
-
-
- public function __construct(array $attributes = [])
- {
- $this->log = false;
-
- parent::__construct($attributes);
- }
-
- public function calculate()
- {
- $this->task->calculate();
- }
-
- public function run(){
-
- if($this->task->status != ScheduledTask::STATUS_ACTIVE) return;
-
- $start_time = microtime(1);
- $this->status = ScheduledTaskInstance::STATUS_RUNNING;
- $this->pid = getmypid();
- $this->save([ 'log'=>false ]);
-
- $exitCode = Artisan::call($this->command);
- $output = Artisan::output();
-
- $this->status = ScheduledTaskInstance::STATUS_COMPLETED;
- $this->ellapsed = microtime(1) - $start_time;
- $this->completed_at = Carbon::now()->toDateTimeString();
- $this->result = $exitCode;
- $this->result_details = [
- 'output'=>$output
- ];
- $this->save();
- }
-
- public function runInBackground(){
-
- chdir(base_path());
-
- exec("php artisan scheduled-task:run --id={$this->id} > /dev/null 2>&1 & disown", $output, $return_var);
- }
-
- public function task(){
-
- return $this->belongsTo('Andiwijaya\AppCore\Models\ScheduledTask', 'task_id');
- }
-
-
- public static function check(){
-
- // Execute task instance
- ScheduledTaskInstance::select('id')
- ->where('status', ScheduledTaskInstance::STATUS_SCHEDULED)
- ->where(function($query){
-
- $query->whereNull('start')
- ->orWhere('start', Carbon::now()->format('Y-m-d H:i') . ':00');
- })
- ->orderBy('id')
- ->chunk(1000, function($instances){
-
- foreach($instances as $instance){
-
- exec("php artisan scheduled-task:run --id={$instance->id} > /dev/null 2>&1 & disown", $output, $return_var);
-
- //Log::info(implode("\n", $output) . "\n" . $return_var);
- }
- });
-
- // Create more instances for repeated task
- ScheduledTask::where('repeat', '>', 0)
- ->chunk(1000, function($tasks){
-
- foreach($tasks as $task){
-
- $task->createInstances();
- }
- });
- }
-}
diff --git a/src/Models/ScheduledTaskResult.php b/src/Models/ScheduledTaskResult.php
index 7b66b28..1b3b64d 100644
--- a/src/Models/ScheduledTaskResult.php
+++ b/src/Models/ScheduledTaskResult.php
@@ -2,9 +2,10 @@
namespace Andiwijaya\AppCore\Models;
+use Andiwijaya\AppCore\Interfaces\VerboseOutputInterface;
use Illuminate\Database\Eloquent\Model;
-class ScheduledTaskResult extends Model{
+class ScheduledTaskResult extends Model implements VerboseOutputInterface{
protected $table = 'scheduled_task_result';
@@ -28,4 +29,11 @@ public function getStatusTextAttribute(){
}
}
+ public function info($text)
+ {
+ $this->verbose .= $text . PHP_EOL;
+
+ $this->save();
+ }
+
}
\ No newline at end of file
diff --git a/src/Models/Traits/FilterableTrait.php b/src/Models/Traits/FilterableTrait.php
index 17b9cda..e4cada5 100644
--- a/src/Models/Traits/FilterableTrait.php
+++ b/src/Models/Traits/FilterableTrait.php
@@ -3,6 +3,7 @@
namespace Andiwijaya\AppCore\Models\Traits;
+use App\Models\Session;
use Carbon\Carbon;
trait FilterableTrait{
@@ -98,46 +99,51 @@ public function scopeFilter($model, array $params, $callback = null){
if(is_null($value)) continue;
if(in_array($key, [ 'columns', 'filters', 'search' ])) continue;
- if(!in_array($key, array_merge($this->getFillable(), $this->getHidden(), $this->getGuarded(), [ 'created_at', 'updated_at' ]))) continue;
+ if(!in_array($key, array_merge($this->getFillable(), $this->getHidden(), $this->getGuarded(), [ 'created_at', 'updated_at' ]))){
+
+ if(strpos($key, '_created_at') !== false) $key = str_replace('_created_at', '.created_at', $key);
+ else if(strpos($key, '_updated_at') !== false) $key = str_replace('_updated_at', '.updated_at', $key);
+ else continue;
+ }
if(isset($value['date_range'])){
switch($value['date_range']){
- case 'today': $model->whereRaw("DATE(`$key`) = ?", [ Carbon::now()->format('Y-m-d') ]); break;
- case 'yesterday': $model->whereRaw("DATE(`$key`) = ?", [ Carbon::now()->addDays(-1)->format('Y-m-d') ]); break;
- case 'tomorrow': $model->whereRaw("DATE(`$key`) = ?", [ Carbon::now()->addDays(1)->format('Y-m-d') ]); break;
+ case 'today': $model->whereRaw("DATE($key) = ?", [ Carbon::now()->format('Y-m-d') ]); break;
+ case 'yesterday': $model->whereRaw("DATE($key) = ?", [ Carbon::now()->addDays(-1)->format('Y-m-d') ]); break;
+ case 'tomorrow': $model->whereRaw("DATE($key) = ?", [ Carbon::now()->addDays(1)->format('Y-m-d') ]); break;
case 'this-week':
- $model->whereRaw("DATE(`$key`) BETWEEN ? AND ?", [
+ $model->whereRaw("DATE($key) BETWEEN ? AND ?", [
Carbon::now()->startOfWeek()->format('Y-m-d'),
Carbon::now()->endOfWeek()->format('Y-m-d'),
]);
break;
case 'this-month':
- $model->whereRaw("DATE(`$key`) BETWEEN ? AND ?", [
+ $model->whereRaw("DATE({$key}) BETWEEN ? AND ?", [
Carbon::now()->startOfMonth()->format('Y-m-d'),
Carbon::now()->endOfMonth()->format('Y-m-d'),
]);
break;
case 'this-quarter':
- $model->whereRaw("DATE(`$key`) BETWEEN ? AND ?", [
+ $model->whereRaw("DATE($key) BETWEEN ? AND ?", [
Carbon::now()->startOfQuarter()->format('Y-m-d'),
Carbon::now()->endOfQuarter()->format('Y-m-d'),
]);
break;
case 'this-year':
- $model->whereRaw("DATE(`$key`) BETWEEN ? AND ?", [
+ $model->whereRaw("DATE($key) BETWEEN ? AND ?", [
Carbon::now()->startOfYear()->format('Y-m-d'),
Carbon::now()->endOfYear()->format('Y-m-d'),
]);
break;
case 'this-decade':
- $model->whereRaw("DATE(`$key`) BETWEEN ? AND ?", [
+ $model->whereRaw("DATE($key) BETWEEN ? AND ?", [
Carbon::now()->startOfDecade()->format('Y-m-d'),
Carbon::now()->endOfDecade()->format('Y-m-d'),
]);
@@ -147,7 +153,7 @@ public function scopeFilter($model, array $params, $callback = null){
$custom_from = date('Y-m-d', strtotime($value['date_range_from']));
$custom_to = date('Y-m-d', strtotime($value['date_range_to']));
- $model->whereRaw("DATE(`$key`) BETWEEN ? AND ?", [
+ $model->whereRaw("DATE($key) BETWEEN ? AND ?", [
$custom_from,
$custom_to,
]);
diff --git a/src/Models/UserNotification.php b/src/Models/UserNotification.php
index f7938ac..8d07f98 100644
--- a/src/Models/UserNotification.php
+++ b/src/Models/UserNotification.php
@@ -7,6 +7,9 @@
class UserNotification extends Model{
+ const TARGET_ALL = -1;
+ const TARGET_ALL_ONLINE = -2;
+
protected $table = 'user_notification';
protected $fillable = [ 'status', 'title', 'body', 'target', 'user_id' ];
@@ -29,37 +32,34 @@ public function save(array $options = [])
{
$return = parent::save($options);
- $this->pushNotification();
-
return $return;
}
- public function pushNotification(){
-
- if(redis_available()) {
- $currentCursor = '0';
- $k = [];
- do {
- $response = Redis::scan($currentCursor, 'MATCH', 'notification*', 'COUNT', 100);
- $currentCursor = $response[0];
- $k = array_merge($k, $response[1]);
- } while ($currentCursor !== '0');
- exc($k);
+ public static function notify($user_id, $title, $description = '', $target = '', $timing = null, $persist = false){
+ $title = str_replace('"', '', $title);
+ $description = str_replace('"', '', $description);
+ $target = str_replace('"', '', $target);
- Redis::publish('notification-1', json_encode($this));
+ if(redis_available()) {
- /*$keys = Redis::keys('name');
+ Redis::publish('user-notif-' . $user_id, json_encode([
+ 'script'=>"$.notify({ title:\"{$title}\", description:\"{$description}\", target:\"{$target}\" });"
+ ]));
+ }
- foreach ($keys as $key){
- \Illuminate\Support\Facades\Log::info("Push notification to {$key}, title: {$this->title}");
+ if($persist){
- Redis::publish($key, json_encode($this));
- }*/
+ $instance = new UserNotification([
+ 'user_id'=>$user_id,
+ 'title'=>$title,
+ 'description'=>$description,
+ 'target'=>$target
+ ]);
+ $instance->save();
}
-
}
}
\ No newline at end of file
diff --git a/src/Services/AuthService.php b/src/Services/AuthService.php
index 9fc7576..a2ff6e1 100644
--- a/src/Services/AuthService.php
+++ b/src/Services/AuthService.php
@@ -70,6 +70,8 @@ public function load()
$this->user = $user;
}
+
+ return $this->user;
}
public function user()
diff --git a/src/Services/WebCacheService.php b/src/Services/WebCacheService.php
index a2eba9a..9980a09 100644
--- a/src/Services/WebCacheService.php
+++ b/src/Services/WebCacheService.php
@@ -113,7 +113,7 @@ public function store(Request $request, $response){
}
else{
- Log::warning("Unable to create cache from response type of " . get_class($response));
+ //Log::warning("Unable to create cache from response type of " . get_class($response));
}
diff --git a/src/WebHistoryServiceProvider.php b/src/WebHistoryServiceProvider.php
index 8dec8db..7438c81 100644
--- a/src/WebHistoryServiceProvider.php
+++ b/src/WebHistoryServiceProvider.php
@@ -65,7 +65,8 @@ public function saveHistory($request, $data){
$queries = $params = [];
- $session_id = Crypt::decrypt($request->cookies->get(strtolower(env('APP_NAME')) . '_session'), false);
+ $session_cookie_value = $request->cookies->get(strtolower(env('APP_NAME')) . '_session');
+ $session_id = $session_cookie_value ? Crypt::decrypt($session_cookie_value, false) : 'N/A';
if(is_assoc($data)) $data = [ $data ];
diff --git a/src/database/default/migrations/2020_06_06_153609_create_scheduled_task_instance_table.php b/src/database/default/migrations/2020_07_22_231332_create_scheduled_task_result_table.php
similarity index 57%
rename from src/database/default/migrations/2020_06_06_153609_create_scheduled_task_instance_table.php
rename to src/database/default/migrations/2020_07_22_231332_create_scheduled_task_result_table.php
index 253859a..7b7a2d5 100644
--- a/src/database/default/migrations/2020_06_06_153609_create_scheduled_task_instance_table.php
+++ b/src/database/default/migrations/2020_07_22_231332_create_scheduled_task_result_table.php
@@ -4,7 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class CreateScheduledTaskInstanceTable extends Migration
+class CreateScheduledTaskResultTable extends Migration
{
/**
* Run the migrations.
@@ -13,24 +13,20 @@ class CreateScheduledTaskInstanceTable extends Migration
*/
public function up()
{
- Schema::create('scheduled_task_instance', function (Blueprint $table) {
+ Schema::create('scheduled_task_result', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('task_id')->unsigned();
- $table->smallInteger('status'); // scheduled, running, completed, failed
- $table->string('command');
+ $table->smallInteger('status');
- $table->dateTime('start')->nullable();
-
- $table->smallInteger('result')->nullable();
- $table->text('result_details')->nullable();
- $table->dateTime('completed_at')->nullable();
- $table->double('ellapsed', 13, 3)->nullable();
+ $table->longText('verbose')->nullable();
$table->timestamps();
-
+ $table->dateTime('started_at')->nullable();
+ $table->dateTime('completed_at')->nullable();
+ $table->double('ellapsed', 6, 3)->nullable();
$table->integer('pid')->nullable();
$table->foreign('task_id')->references('id')->on('scheduled_task')->onDelete('cascade')->onUpdate('cascade');
@@ -44,6 +40,6 @@ public function up()
*/
public function down()
{
- Schema::dropIfExists('scheduled_task_instance');
+ Schema::dropIfExists('scheduled_task_result');
}
}
diff --git a/src/helpers.php b/src/helpers.php
index 1b515e3..046d41b 100644
--- a/src/helpers.php
+++ b/src/helpers.php
@@ -5,6 +5,8 @@
* Check if variable is assosiative array
*/
+use Illuminate\Support\Str;
+
if(!function_exists('is_assoc')){
function is_assoc($array) {
if(gettype($array) == "array")
@@ -14,7 +16,7 @@ function is_assoc($array) {
}
if (! function_exists('exc')) {
- function exc($message)
+ function exc($message = '')
{
if(is_array($message)) $message = json_encode($message);
throw new \Andiwijaya\AppCore\Exceptions\KnownException($message);
@@ -400,40 +402,54 @@ function array_index($arr, $indexes, $objResult = false){
if(!is_array($arr)) return null;
$result = array();
+ $indexes_is_callback = is_callable($indexes);
+
for($i = 0 ; $i < count($arr) ; $i++){
$obj = $arr[$i];
- switch(count($indexes)){
- case 1 :
- $idx0 = $indexes[0];
- if(!isset($obj[$idx0])) continue;
- if(!isset($result[$obj[$idx0]])) $result[$obj[$idx0]] = array();
- $result[$obj[$idx0]][] = $obj;
- break;
- case 2 :
- $idx0 = $indexes[0];
- $idx1 = $indexes[1];
- if(!isset($obj[$idx0]) || !isset($obj[$idx1])) continue;
- $key0 = $obj[$idx0];
- $key1 = $obj[$idx1];
- if(!isset($result[$key0])) $result[$key0] = array();
- if(!isset($result[$key0][$key1])) $result[$key0][$key1] = array();
- $result[$key0][$key1][] = $obj;
- break;
- case 3 :
- $idx0 = $indexes[0];
- $idx1 = $indexes[1];
- $idx2 = $indexes[2];
- if(!isset($obj[$idx0]) || !isset($obj[$idx1]) || !isset($obj[$idx2])) continue;
- $key0 = $obj[$idx0];
- $key1 = $obj[$idx1];
- $key2 = $obj[$idx2];
- if(!isset($result[$key0])) $result[$key0] = array();
- if(!isset($result[$key0][$key1])) $result[$key0][$key1] = array();
- $result[$key0][$key1][$key2] = $obj;
- break;
- default:
- throw new Exception("Unsupported index level.");
+ if($indexes_is_callback){
+
+ $key = call_user_func_array($indexes, [ $obj ]);
+ if(!isset($result[$key])) $result[$key] = [];
+ $result[$key][] = $obj;
+ }
+ else{
+
+ switch(count($indexes)){
+ case 1 :
+ $idx0 = $indexes[0];
+ if(isset($obj[$idx0])){
+ if(!isset($result[$obj[$idx0]])) $result[$obj[$idx0]] = array();
+ $result[$obj[$idx0]][] = $obj;
+ }
+ break;
+ case 2 :
+ $idx0 = $indexes[0];
+ $idx1 = $indexes[1];
+ if(isset($obj[$idx0]) && isset($obj[$idx1])){
+ $key0 = $obj[$idx0];
+ $key1 = $obj[$idx1];
+ if(!isset($result[$key0])) $result[$key0] = array();
+ if(!isset($result[$key0][$key1])) $result[$key0][$key1] = array();
+ $result[$key0][$key1][] = $obj;
+ }
+ break;
+ case 3 :
+ $idx0 = $indexes[0];
+ $idx1 = $indexes[1];
+ $idx2 = $indexes[2];
+ if(isset($obj[$idx0]) && !isset($obj[$idx1]) && !isset($obj[$idx2])){
+ $key0 = $obj[$idx0];
+ $key1 = $obj[$idx1];
+ $key2 = $obj[$idx2];
+ if(!isset($result[$key0])) $result[$key0] = array();
+ if(!isset($result[$key0][$key1])) $result[$key0][$key1] = array();
+ $result[$key0][$key1][$key2] = $obj;
+ }
+ break;
+ default:
+ throw new Exception("Unsupported index level.");
+ }
}
}
@@ -476,32 +492,35 @@ function array_index_obj($arr, $indexes, $objResult = false)
switch (count($indexes)) {
case 1 :
$idx0 = $indexes[0];
- if (!isset($obj->{$idx0})) continue;
- if (!isset($result[$obj->{$idx0}])) $result[$obj->{$idx0}] = array();
- $result[$obj->{$idx0}][] = $obj;
+ if (isset($obj->{$idx0})) {
+ if (!isset($result[$obj->{$idx0}])) $result[$obj->{$idx0}] = array();
+ $result[$obj->{$idx0}][] = $obj;
+ }
break;
case 2 :
$idx0 = $indexes[0];
$idx1 = $indexes[1];
- if (!isset($obj->{$idx0}) || !isset($obj->{$idx1})) continue;
- $key0 = $obj->{$idx0};
- $key1 = $obj->{$idx1};
- if (!isset($result[$key0])) $result[$key0] = array();
- if (!isset($result[$key0][$key1])) $result[$key0][$key1] = array();
- $result[$key0][$key1][] = $obj;
+ if (isset($obj->{$idx0}) && isset($obj->{$idx1})){
+ $key0 = $obj->{$idx0};
+ $key1 = $obj->{$idx1};
+ if (!isset($result[$key0])) $result[$key0] = array();
+ if (!isset($result[$key0][$key1])) $result[$key0][$key1] = array();
+ $result[$key0][$key1][] = $obj;
+ }
break;
case 3 :
$idx0 = $indexes[0];
$idx1 = $indexes[1];
$idx2 = $indexes[2];
- if (!isset($obj->{$idx0}) || !isset($obj->{$idx1}) || !isset($obj->{$idx2})) continue;
- $key0 = $obj->{$idx0};
- $key1 = $obj->{$idx1};
- $key2 = $obj->{$idx2};
-
- if (!isset($result[$key0])) $result[$key0] = array();
- if (!isset($result[$key0][$key1])) $result[$key0][$key1] = array();
- $result[$key0][$key1][$key2][] = $obj;
+ if (isset($obj->{$idx0}) && !isset($obj->{$idx1}) && !isset($obj->{$idx2})){
+ $key0 = $obj->{$idx0};
+ $key1 = $obj->{$idx1};
+ $key2 = $obj->{$idx2};
+
+ if (!isset($result[$key0])) $result[$key0] = array();
+ if (!isset($result[$key0][$key1])) $result[$key0][$key1] = array();
+ $result[$key0][$key1][$key2][] = $obj;
+ }
break;
default:
throw new Exception("Unsupported index level.");
@@ -1026,6 +1045,7 @@ function list_page_filter_item($key, $param){
$custom_from = \Carbon\Carbon::now()->addDays(-7)->format('j M Y');
$custom_to = \Carbon\Carbon::now()->format('j M Y');
+ $key = Str::slug($key);
$html .= <<
@@ -1309,22 +1329,124 @@ function imgresizer($image, $resize){
}
}
-if(!function_exists('appcore_boot')){
+if(!function_exists('checked_if')){
+
+ function checked_if($key, $arr){
+
+ if(is_array($arr))
+ return in_array($key, $arr) ? ' checked' : '';
+ return '';
+ }
+}
+
+if(!function_exists('action_route')){
- function appcore_boot($provider){
+ function action_route($namespace){
+ $f = function(\Illuminate\Http\Request $request) use($namespace){
+ $namespace = 'Admin';
+ if(!empty($namespace)) $namespace .= '\\';
- }
+ $method = $request->method();
+ $path = $request->path();
+ $paths = $path != '/' ? explode('/', $path) : [];
+ $key = null;
+ $action = explode('|', $request->input('action'))[0] ?? null;
+
+ if(preg_match('/^\d+$/', end($paths)) || in_array(end($paths), [ 'create' ])){
+ $key = end($paths);
+ $paths = array_splice($paths, 0, count($paths) - 1);
+ }
+
+ $controller = "App\\Http\\Controllers\\{$namespace}" . Str::ucfirst(Str::camel(count($paths) > 0 ? implode('-', $paths) : 'index') . 'Controller');
+ if(class_exists($controller)){
+
+ $controller = new $controller();
+
+ if(!$key){
+
+ switch($method){
+
+ case 'GET':
+ $method = Str::camel($action ? $action : 'view');
+
+ return call_user_func_array([ $controller, $method ], [ $request ]);
+
+ case 'POST':
+ $method = Str::camel($action ? $action : 'save');
+
+ return call_user_func_array([ $controller, $method ], [ $request ]);
+
+ case 'PATCH':
+ $method = Str::camel($action ? $action : 'update');
+
+ return call_user_func_array([ $controller, $method ], [ $request ]);
+ }
+
+ }
+ else{
+
+ switch($method){
+
+ case 'GET':
+ $method = Str::camel($action ? $action : ($key == 'create' ? 'create' : 'open'));
+
+ return call_user_func_array([ $controller, $method ], [ $request, $key ]);
+
+ case 'DELETE':
+ $method = Str::camel($action ? $action : 'destroy');
+
+ return call_user_func_array([ $controller, $method ], [ $request, $key ]);
+
+ }
+ }
+
+
+ }
+
+ else{
+
+ return json_encode([
+ $namespace,
+ $method,
+ $path,
+ $controller,
+ class_exists($controller)
+ ]);
+ }
+
+ };
+
+ return function() use($f){
+
+ \Illuminate\Support\Facades\Route::any('', $f);
+ \Illuminate\Support\Facades\Route::any('{p1}', $f);
+ \Illuminate\Support\Facades\Route::any('{p1}/{p2}', $f);
+ \Illuminate\Support\Facades\Route::any('{p1}/{p2}/{p3}', $f);
+ };
+ };
}
-if(!function_exists('checked_if')){
+if(!function_exists('greeting')){
- function checked_if($key, $arr){
+ function greeting($name = ''){
- if(is_array($arr))
- return in_array($key, $arr) ? ' checked' : '';
- return '';
+ $hour = \Carbon\Carbon::now()->format('H');
+ if($hour >= 5 && $hour < 11)
+ $greeting = __('Good morning');
+ elseif($hour >= 11 && $hour < 15)
+ $greeting = __('Good afternoon');
+ elseif($hour >= 15 && $hour < 19)
+ $greeting = __('Good evening');
+ else
+ $greeting = __('Good night');
+
+ $greeting .= !empty($name) ? ', ' . $name : '';
+
+ return $greeting;
}
-}
\ No newline at end of file
+
+}
+
diff --git a/src/views/components/chat-admin-message-head.blade.php b/src/views/components/chat-admin-message-head.blade.php
index a241ac4..d9007d0 100644
--- a/src/views/components/chat-admin-message-head.blade.php
+++ b/src/views/components/chat-admin-message-head.blade.php
@@ -11,15 +11,24 @@
@component('andiwijaya::components.chat-admin-online-status', compact('customer_is_online', 'discussion'))@endcomponent
- @if(isset($discussion->extra['phone_number']))
+ @if(isset($discussion->extra['phone_number']) && strlen($discussion->extra['phone_number']) > 0)
{{ $discussion->extra['phone_number'] }}
+ @elseif(strlen($discussion->mobile_number) > 0)
+
+ {{ $discussion->mobile_number }}
+
@endif
- @if(isset($discussion->extra['whatsapp_number']))
+
+ @if(isset($discussion->extra['whatsapp_number']) && strlen($discussion->extra['whatsapp_number']) > 0)
{{ $discussion->extra['whatsapp_number'] }}
+ @elseif(strlen($discussion->whatsapp_number) > 0)
+
+ {{ $discussion->whatsapp_number }}
+
@endif
diff --git a/src/views/components/syslog-edit.blade.php b/src/views/components/syslog-edit.blade.php
index ff98589..4505dcc 100644
--- a/src/views/components/syslog-edit.blade.php
+++ b/src/views/components/syslog-edit.blade.php
@@ -11,16 +11,37 @@
-
+
Type
{{ $instance->type_text }}
-
+
Console
{{ $instance->data['console'] ? 'Yes' : 'No' }}
+
+ Session ID
+ {{ $instance->data['session_id'] ?? '-' }}
+
+
+
+
+ IP Address
+ {{ $instance->data['remote_ip'] ?? '-' }}
+
+
+ Timestamp
+ {{ $instance->created_at }}
+
+
+
+
+ User Agent
+ {{ $instance->data['user_agent'] ?? '-' }}
+
+
Message
{{ $instance->message }}
@@ -41,8 +62,18 @@
{!! $instance->data['traces'] !!}
+
+
Session
+
{!! json_encode($instance->data['session'] ?? [], JSON_PRETTY_PRINT) !!}
+
+
+
+
Cookies
+
{!! json_encode($instance->data['cookies'] ?? [], JSON_PRETTY_PRINT) !!}
+
+
diff --git a/src/views/sections/cms-import-completed2.blade.php b/src/views/sections/cms-import-completed2.blade.php
new file mode 100644
index 0000000..e9066f5
--- /dev/null
+++ b/src/views/sections/cms-import-completed2.blade.php
@@ -0,0 +1,34 @@
+
\ No newline at end of file