Skip to content

Instantly share code, notes, and snippets.

@hannesvdvreken
Created April 18, 2014 22:24
Show Gist options
  • Save hannesvdvreken/11066972 to your computer and use it in GitHub Desktop.
Save hannesvdvreken/11066972 to your computer and use it in GitHub Desktop.
LaravelPHP artisan command to search the apibunny maze
<?php
use Guzzle\Http\Client;
use Guzzle\Http\Exception\BadResponseException;
use Illuminate\Console\Command;
use Illuminate\Foundation\Application;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class MazeCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'maze:search';
/**
* @var array
*/
protected $queue = [];
/**
* @var array
*/
protected $done = [];
/**
* @var string
*/
protected $baseUrl = 'http://apibunny.com/';
/**
* @var Illuminate\Foundation\Application
*/
protected $app;
/**
* @var Guzzle\Http\Client
*/
protected $client;
/**
* The console command description.
*
* @var string
*/
protected $description = 'Search the apibunny.com maze';
/**
* Constructor injection
*
* @param Guzzle\Http\Client $client
*/
public function __construct(Client $client)
{
// Call the parent constructor.
parent::__construct();
// Assign injected dependencies.
$this->client = $client;
// Setup some stuff.
$this->init();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function fire()
{
// Ask the first cell id.
$id = $this->ask('What is the ID of the first cell?');
// Do the first request.
$user = $this->process($id);
while (is_null($user)) {
// Getting a random id from the queue and add it to the done list.
$this->done[] = $id = head(array_splice($this->queue, rand(0, count($this->queue) - 1), 1));
// Display some info.
$this->info("visiting $id");
// Get the new id.
$user = $this->process($id);
}
// Print out the winning info.
$this->info(json_encode($user, JSON_PRETTY_PRINT));
}
/**
* Get a cell and process the links to neighbouring cells.
*
* @param string $id
*/
protected function process($id)
{
// Do the request.
$result = $this->client->get("cells/$id")->send()->json();
// Loop result.
foreach (array_get($result, 'cells') as $cell) {
// If the exit link is present: exit.
if (array_key_exists('exit_link', $cell)) {
// Return the result.
return $this->post(array_get($cell, 'exit_link'));
}
// Add links to the queue.
$this->addLinks(array_get($cell, 'links', array()));
}
}
/**
* Add links to the queue.
*
* @param array $links
* @return void
*/
protected function addLinks(array $links)
{
// Loop the links.
foreach ($links as $name => $id) {
// If it hasn't been visited...
if (!in_array($id, $this->done) && !in_array($id, $this->queue) && $name != 'maze') {
// ... add it to the queue
$this->queue[] = $id;
}
}
}
/**
* Post to the exit link.
*
* @param string $href
*/
protected function post($href)
{
// Ask for the handle.
$handle = $this->ask('What is your twitter handle?');
// Remove the submit part.
$href = preg_replace('/\ \[submit\:.*\]$/', '', $href);
// Build json api post body
$body = [
'users' => [
['twitter_handle' => $handle]
]
];
// Send json.
$headers = ['Content-Type' => 'application/vnd.api+json'];
// Try posting the data.
try {
return $user = $this->client->post($href, $headers, json_encode($body))->send()->json();
} catch (BadResponseException $exception) {
return $user = $exception->getResponse()->json();
}
}
/**
* Init the Guzzle client.
*
* @return void
*/
protected function init()
{
$this->client->setBaseUrl($this->baseUrl);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment