A couple of weeks ago a company sent me this coding challenge:
Please write a PHP web application and send it back to me as zip file:
- Which waits for a user action, like clicking buttons. According to these actions some data (see further below) should be:
- either shown nicely formatted on the screen
- or downloaded as CSV file
- You can either download the data on each request during the runtime of your PHP program or load the data from a database (in this case do NOT provide a DB dump, but a script which automatically transfers the data from the remote location to the DB)
- Preferably the implementation should be written in "clean code", separate concerns using pattern like MVC, be object oriented, very good testable, best even already contain Unit tests and maybe even follow the KISS and SOLID principles
AND
- Country list
- The data should be a list of countries with their country code
- Please download the base data from here
- Afterwards you will have to change the whole list from "Country code - Country name" to "CountryName - CountryCode" and sorts the list by CountryName
Is my solution okay? How can it be improved?
Controller:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Welcome extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->model('country_model');
}
public function index() {
$data = array();
if (isset($_POST['run'])) {
$this->_save_data();
$data['list'] = $this->country_model->get_countries(252)->result();
}
$this->load->helper('form');
$this->load->view('welcome_message', $data);
}
private function _save_data() {
// Get a file into an array. In this example we'll go through HTTP to get
// the HTML source of a URL.
$lines = file('http://pastebin.com/raw.php?i=943PQQ0n');
$lineNo = 0;
$startLine = 4;
$endLine = 255;
// Loop through our array, show HTML source as HTML source; and line numbers too.
foreach ($lines as $line_num => $line) {
$lineNo++;
if ($lineNo >= $startLine) {
$country = explode(' ', trim(htmlspecialchars($line)));
if (!isset($country[0]) || !isset($country[1])) {
continue;
}
$count = $this->country_model->count_by_code($country[0]);
if (!$count) {
$this->country_model->insert_entry($country[0], $country[1]);
}
}
if ($lineNo == $endLine) {
break;
}
}
}
}
Model:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Country_model extends CI_Model {
public $table = 'country';
public function __construct() {
// Call the CI_Model constructor
parent::__construct();
$this->load->database();
}
public function insert_entry($country_code, $country_name) {
$data['country_code'] = $country_code;
$data['country_name'] = $country_name;
$this->db->insert($this->table, $data);
}
function count_by_code($country_code) {
$this->db->where('country_code', $country_code);
return $this->db->count_all_results($this->table);
}
function get_countries($limit) {
$this->db->select('country_code, country_name');
$this->db->order_by("country_name", "asc");
return $this->db->get($this->table, 0, $limit);
}
}
View:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Welcome to My Task</title>
</head>
<body>
<div id="container">
<h1>Welcome to My Task!</h1>
<div id="body">
<?php echo form_open(); ?>
<input type="submit" value="Get Country List" name="run"/>
<?php echo form_close(); ?>
<br>
<?php
if (isset($list)) {
foreach ($list as $value) {
echo $value->country_name . ' - ' . $value->country_code . '<br>';
}
}
?>
</div>
<p class="footer">Page rendered in <strong>{elapsed_time}</strong> seconds. <?php echo (ENVIRONMENT === 'development') ? 'CodeIgniter Version <strong>' . CI_VERSION . '</strong>' : '' ?></p>
</div>
</body>
</html>