Skip to content

Commit

Permalink
Merge cb9648b into 1b8b6fb
Browse files Browse the repository at this point in the history
  • Loading branch information
polinart committed Aug 7, 2019
2 parents 1b8b6fb + cb9648b commit 2b69fba
Show file tree
Hide file tree
Showing 9 changed files with 405 additions and 1 deletion.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"roboc/laravel-glide": "^1.1.0",
"spatie/laravel-sluggable": "^2.1.0",
"maatwebsite/excel": "^3.0.5",
"unisharp/laravel-filemanager": "^1.8.5"
"unisharp/laravel-filemanager": "^1.8.5",
"ext-curl": "*"
},
"require-dev" : {
"satooshi/php-coveralls": "^1.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddUrlStatusToRedirectsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('redirects', function (Blueprint $table) {
$table->boolean('status')->default(0);
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('redirects', function (Blueprint $table) {
$table->dropColumn('status');
});
}
}
109 changes: 109 additions & 0 deletions src/Console/Commands/RedirectHealthCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace Arbory\Base\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Arbory\Base\Jobs\UpdateRedirectUrlStatus;
use Illuminate\Foundation\Bus\DispatchesJobs;

class RedirectHealthCommand extends Command
{
use DispatchesJobs;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'arbory.redirect-health
{ids=[] : The array of IDs from redirects table to check (if not provided then would be selected all redirects table entries)}
{--errors : Show curl request errors}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Runs an URL healthcheck to verify the redirects table `to_url` is available and update `status` field in table';

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
try {
$ids = $this->getIDs();
$job = new UpdateRedirectUrlStatus($ids);

$this->info('Start to check '.count($ids).' entries...');

$this->dispatchNow($job);
$result = $job->getResult();

if (! empty($result) && count($result->getInvalidUrlList())) {
$this->warn("\nInvalid URLs list:");
foreach ($result->getInvalidUrlList() as $url) {
$this->warn($url);
}
}

if ($this->option('errors') && ! empty($result) && count($result->getErrors())) {
foreach ($result->getErrors() as $url => $err) {
$this->error("Request to $url - $err");
}
}

$this->warn("\nInvalid entries: {$result->getInvalidCount()}");
$this->info("Valid entries: {$result->getValidCount()}");
} catch (\Exception $e) {
$this->error('Redirects healthcheck failed with an exception');
$this->error($e->getMessage());

return 2;
}

return 0;
}

/**
* @return array
*/
public function selectAllRedirectIds()
{
$results = DB::table('redirects')->where('id', '>', 0)->pluck('id')->toArray();

return $results;
}

/**
* @param array $entryIds
* @param int $status
*/
public function setStatus(array $entryIds, int $status)
{
DB::table('redirects')->whereIn('id', $entryIds)->update(['status' => $status]);
}

/**
* @return array
*/
private function getIDs()
{
$param = $this->argument('ids');

$final_ids = [];
foreach (explode(',', $param) as $id) {
if (is_numeric($id)) {
$final_ids[] = $id;
}
}

if (count($final_ids)) {
return $final_ids;
}

return $this->selectAllRedirectIds();
}
}
2 changes: 2 additions & 0 deletions src/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Arbory\Base\Console;

use Arbory\Base\Console\Commands\SeedCommand;
use Arbory\Base\Console\Commands\RedirectHealthCommand;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

/**
Expand All @@ -15,5 +16,6 @@ class Kernel extends ConsoleKernel
*/
protected $commands = [
SeedCommand::class,
RedirectHealthCommand::class,
];
}
93 changes: 93 additions & 0 deletions src/Jobs/UpdateRedirectUrlStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace Arbory\Base\Jobs;

use Illuminate\Log\Logger;
use Illuminate\Support\Facades\DB;
use Arbory\Base\RedirectHealthChecker;
use Illuminate\Contracts\Queue\ShouldQueue;

class UpdateRedirectUrlStatus implements ShouldQueue
{
/**
* @var Logger
*/
protected $logger;

/**
* @var array
*/
protected $redirectIds;

/** @var RedirectHealthChecker */
private $redirectHealthChecker;

/**
* UpdateRedirectUrlStatus constructor.
* @param array $redirectIds
*/
public function __construct(array $redirectIds)
{
$this->redirectIds = $redirectIds;
}

/**
* Execute the job.
*
* @param Logger $logger
* @return void
*/
public function handle(Logger $logger)
{
$this->logger = $logger;

$this->checkAndUpdateRedirectStatus();
}

/**
* @return void
*/
private function checkAndUpdateRedirectStatus()
{
try {
$redirects = $this->selectRedirects($this->redirectIds);

$redirectHealthChecker = new RedirectHealthChecker($redirects);
$redirectHealthChecker->check();

$this->updateStatusBulk($redirectHealthChecker->getValidIds(), true);
$this->updateStatusBulk($redirectHealthChecker->getInvalidIds(), false);

$this->redirectHealthChecker = $redirectHealthChecker;
} catch (\Exception $e) {
$this->logger->warning($e->getMessage());
}
}

/**
* @param array $ids
* @return \Illuminate\Support\Collection
*/
public function selectRedirects(array $ids)
{
$results = DB::table('redirects')->whereIn('id', $ids)->get(['id', 'to_url']);

return $results;
}

/*
* @return void
*/
public function updateStatusBulk(array $entryIds, int $status)
{
DB::table('redirects')->whereIn('id', $entryIds)->update(['status' => $status]);
}

/**
* @return RedirectHealthChecker|null
*/
public function getResult()
{
return $this->redirectHealthChecker ?? null;
}
}
24 changes: 24 additions & 0 deletions src/Observers/RedirectObserver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Arbory\Base\Observers;

use Arbory\Base\Pages\Redirect;
use Arbory\Base\Jobs\UpdateRedirectUrlStatus;
use Illuminate\Foundation\Bus\DispatchesJobs;

class RedirectObserver
{
use DispatchesJobs;

/**
* Handle the redirect "saved" event.
*
* @param Redirect $redirect
* @return void
*/
public function saved(Redirect $redirect)
{
$job = new UpdateRedirectUrlStatus([$redirect->id]);
$this->dispatchNow($job);
}
}
1 change: 1 addition & 0 deletions src/Pages/Redirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Redirect extends Model
protected $fillable = [
'from_url',
'to_url',
'status',
];

/**
Expand Down
6 changes: 6 additions & 0 deletions src/Providers/ArboryServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

use Arbory\Base\Menu\Menu;
use Arbory\Base\Admin\Admin;
use Arbory\Base\Pages\Redirect;
use Arbory\Base\Services\AssetPipeline;
use Illuminate\Support\ServiceProvider;
use Arbory\Base\Observers\RedirectObserver;
use Arbory\Base\Console\Commands\SeedCommand;
use Arbory\Base\Console\Commands\InstallCommand;
use Arbory\Base\Console\Commands\CreateUserCommand;
use Arbory\Base\Console\Commands\RedirectHealthCommand;
use Arbory\Base\Services\Authentication\SecurityStrategy;
use Arbory\Base\Services\Authentication\SessionSecurityService;

Expand All @@ -29,6 +32,8 @@ public function boot()
$this->registerCommands();
$this->registerLocales();

Redirect::observe(RedirectObserver::class);

$this->app->singleton(SecurityStrategy::class, function () {
return $this->app->make(SessionSecurityService::class);
});
Expand Down Expand Up @@ -73,6 +78,7 @@ private function registerCommands()
'arbory.seed' => SeedCommand::class,
'arbory.create-user' => CreateUserCommand::class,
'arbory.install' => InstallCommand::class,
'arbory.redirect-health' => RedirectHealthCommand::class,
];

foreach ($commands as $containerKey => $commandClass) {
Expand Down
Loading

0 comments on commit 2b69fba

Please sign in to comment.