Sorting a list by country name Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)Creating a table for use in ExcelQuerying a database with PHPIs this a good structure for my website?Website for updating a divMVC JavaScript app to display athletes by countryGet rows from a table and add rows to google chartsGetting data from a server for raffle game and saving data back to the serverUse parameter to filter results in a database without directly allowing users to access databaseDynamically displaying or hiding checkboxes based on region selection country. Also select All / None includedAdding ID to body tag from variable defined in URL

How to motivate offshore teams and trust them to deliver?

Is 1 ppb equal to 1 μg/kg?

Sorting numerically

Why did the IBM 650 use bi-quinary?

Models of set theory where not every set can be linearly ordered

ListPlot join points by nearest neighbor rather than order

Why is black pepper both grey and black?

Why there are no cargo aircraft with "flying wing" design?

Right-skewed distribution with mean equals to mode?

What are the pros and cons of Aerospike nosecones?

Is there a concise way to say "all of the X, one of each"?

How do I keep my slimes from escaping their pens?

Withdrew £2800, but only £2000 shows as withdrawn on online banking; what are my obligations?

How to recreate this effect in Photoshop?

Why does Python start at index 1 when iterating an array backwards?

What happens to sewage if there is no river near by?

Check which numbers satisfy the condition [A*B*C = A! + B! + C!]

How to bypass password on Windows XP account?

How can whole tone melodies sound more interesting?

Single word antonym of "flightless"

Java 8 stream max() function argument type Comparator vs Comparable

Can inflation occur in a positive-sum game currency system such as the Stack Exchange reputation system?

Stars Make Stars

What are 'alternative tunings' of a guitar and why would you use them? Doesn't it make it more difficult to play?



Sorting a list by country name



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)Creating a table for use in ExcelQuerying a database with PHPIs this a good structure for my website?Website for updating a divMVC JavaScript app to display athletes by countryGet rows from a table and add rows to google chartsGetting data from a server for raffle game and saving data back to the serverUse parameter to filter results in a database without directly allowing users to access databaseDynamically displaying or hiding checkboxes based on region selection country. Also select All / None includedAdding ID to body tag from variable defined in URL



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








2












$begingroup$


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])
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>









share|improve this question











$endgroup$


















    2












    $begingroup$


    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])
    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>









    share|improve this question











    $endgroup$














      2












      2








      2


      1



      $begingroup$


      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])
      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>









      share|improve this question











      $endgroup$




      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])
      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>






      php sorting mvc codeigniter






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 9 '18 at 18:16









      Sᴀᴍ Onᴇᴌᴀ

      10.6k62168




      10.6k62168










      asked May 30 '16 at 8:08









      WaqlehWaqleh

      1144




      1144




















          2 Answers
          2






          active

          oldest

          votes


















          2












          $begingroup$

          Looks pretty good. Here are just some thoughts but nothing major:



          • It would be more future-proof (and probably efficient) to use regular expressions in lieu of parsing hard-coded line numbers (in case the data has rows added later):



          • For the _save_data() you could parse like so:



            $string = 'THE CONTENT FROM THE COUNTRIES LIST PAGE';
            $sub = preg_replace('/.+?(?=ADsss)/s', '', $string); // this strips the pre-text
            $list = preg_split('/$R?^/m', $sub); // This splits by line
            $countries = array();

            foreach ($list as $item)
            $arr = explode(' ', $item);
            $countries[$arr[0]] = $arr[1];


            asort($countries); // sort by values

            //print_r($countries);
            /** Array
            (
            [AF] => Afghanistan
            [AL] => Albania
            [DZ] => Algeria
            [AS] => American Samoa
            [AD] => Andorra
            ... */


            This way you do not need to pass limit to get_countries().



          • You could also use a view helper or template for the output section to better format. <br> can get pretty ugly so I would do a list (<ul>) or something. Overall, it seems pretty logical.






          share|improve this answer











          $endgroup$




















            0












            $begingroup$

            Feedback



            The code looks good so far. There appears to be good separation between the model, the view and the controller. I like how the model methods are concise - none more than 4 lines. The controller method _save_data() is a little on the lengthy side but hopefully the feedback below and in the answer by Tomanow will allow you to improve that method.



            Suggestions



            Regular expression



            I agree with Tomanow's answer (except that you might not need to worry about stripping the pre-text, presuming that the pattern matching only matches country codes and names). A regular expression can be used in _save_data() to match each relevant row, and using a named sub-pattern, the code and name of each country can be selected:



            $pattern = '/^'. //beginning of line
            '(?P<country_code>[A-Za-z]2,4)'. // named sub-pattern for code: 2-4 alpha chars
            's3'. //3 whitespace characters
            '(?P<country_name>[A-Za-z()s.,'-]+)'. // named sub-pattern for name
            '$/'; //end of line


            If that pattern matches any rows, $matches['code'] will have the country code and $matches['name'] will have the country name. In theory, $matches could be sent to the insert_entry() model method, though that might be a weird design to accept the fields to insert directly (and the numeric indexes might need to be removed).



            In theory the logic involving $startLine and $endLine can be removed by simply checking of the pattern matches.



            $lines = file('http://pastebin.com/raw.php?i=943PQQ0n');
            $pattern = '/^(?P<country_code>[A-Za-z]2,4)s3(?P<country_name>[A-Za-z()s.,'-]+)$/';

            // Loop through our array, show HTML source as HTML source; and line numbers too.
            foreach ($lines as $line_num => $line)
            preg_match($pattern, $line, $matches);
            if (count($matches))
            $count = $this->country_model->count_by_code($matches['country_code']);
            if (!$count)
            $this->country_model->insert_entry($matches['country_code'], $matches['country_name']);





            See a demonstration of the matching here in this playground example.



            Useless variable $lineNo



            In your method _save_data() there is a variable $lineNo that gets incremented each time. If you needed the count of each line, the variable $line_num (from the foreach statement) could be used instead (and added 1 to)...



            foreach ($lines as $line_num => $line) {
            $lineNo++;





            share|improve this answer











            $endgroup$













              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "196"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f129657%2fsorting-a-list-by-country-name%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              2












              $begingroup$

              Looks pretty good. Here are just some thoughts but nothing major:



              • It would be more future-proof (and probably efficient) to use regular expressions in lieu of parsing hard-coded line numbers (in case the data has rows added later):



              • For the _save_data() you could parse like so:



                $string = 'THE CONTENT FROM THE COUNTRIES LIST PAGE';
                $sub = preg_replace('/.+?(?=ADsss)/s', '', $string); // this strips the pre-text
                $list = preg_split('/$R?^/m', $sub); // This splits by line
                $countries = array();

                foreach ($list as $item)
                $arr = explode(' ', $item);
                $countries[$arr[0]] = $arr[1];


                asort($countries); // sort by values

                //print_r($countries);
                /** Array
                (
                [AF] => Afghanistan
                [AL] => Albania
                [DZ] => Algeria
                [AS] => American Samoa
                [AD] => Andorra
                ... */


                This way you do not need to pass limit to get_countries().



              • You could also use a view helper or template for the output section to better format. <br> can get pretty ugly so I would do a list (<ul>) or something. Overall, it seems pretty logical.






              share|improve this answer











              $endgroup$

















                2












                $begingroup$

                Looks pretty good. Here are just some thoughts but nothing major:



                • It would be more future-proof (and probably efficient) to use regular expressions in lieu of parsing hard-coded line numbers (in case the data has rows added later):



                • For the _save_data() you could parse like so:



                  $string = 'THE CONTENT FROM THE COUNTRIES LIST PAGE';
                  $sub = preg_replace('/.+?(?=ADsss)/s', '', $string); // this strips the pre-text
                  $list = preg_split('/$R?^/m', $sub); // This splits by line
                  $countries = array();

                  foreach ($list as $item)
                  $arr = explode(' ', $item);
                  $countries[$arr[0]] = $arr[1];


                  asort($countries); // sort by values

                  //print_r($countries);
                  /** Array
                  (
                  [AF] => Afghanistan
                  [AL] => Albania
                  [DZ] => Algeria
                  [AS] => American Samoa
                  [AD] => Andorra
                  ... */


                  This way you do not need to pass limit to get_countries().



                • You could also use a view helper or template for the output section to better format. <br> can get pretty ugly so I would do a list (<ul>) or something. Overall, it seems pretty logical.






                share|improve this answer











                $endgroup$















                  2












                  2








                  2





                  $begingroup$

                  Looks pretty good. Here are just some thoughts but nothing major:



                  • It would be more future-proof (and probably efficient) to use regular expressions in lieu of parsing hard-coded line numbers (in case the data has rows added later):



                  • For the _save_data() you could parse like so:



                    $string = 'THE CONTENT FROM THE COUNTRIES LIST PAGE';
                    $sub = preg_replace('/.+?(?=ADsss)/s', '', $string); // this strips the pre-text
                    $list = preg_split('/$R?^/m', $sub); // This splits by line
                    $countries = array();

                    foreach ($list as $item)
                    $arr = explode(' ', $item);
                    $countries[$arr[0]] = $arr[1];


                    asort($countries); // sort by values

                    //print_r($countries);
                    /** Array
                    (
                    [AF] => Afghanistan
                    [AL] => Albania
                    [DZ] => Algeria
                    [AS] => American Samoa
                    [AD] => Andorra
                    ... */


                    This way you do not need to pass limit to get_countries().



                  • You could also use a view helper or template for the output section to better format. <br> can get pretty ugly so I would do a list (<ul>) or something. Overall, it seems pretty logical.






                  share|improve this answer











                  $endgroup$



                  Looks pretty good. Here are just some thoughts but nothing major:



                  • It would be more future-proof (and probably efficient) to use regular expressions in lieu of parsing hard-coded line numbers (in case the data has rows added later):



                  • For the _save_data() you could parse like so:



                    $string = 'THE CONTENT FROM THE COUNTRIES LIST PAGE';
                    $sub = preg_replace('/.+?(?=ADsss)/s', '', $string); // this strips the pre-text
                    $list = preg_split('/$R?^/m', $sub); // This splits by line
                    $countries = array();

                    foreach ($list as $item)
                    $arr = explode(' ', $item);
                    $countries[$arr[0]] = $arr[1];


                    asort($countries); // sort by values

                    //print_r($countries);
                    /** Array
                    (
                    [AF] => Afghanistan
                    [AL] => Albania
                    [DZ] => Algeria
                    [AS] => American Samoa
                    [AD] => Andorra
                    ... */


                    This way you do not need to pass limit to get_countries().



                  • You could also use a view helper or template for the output section to better format. <br> can get pretty ugly so I would do a list (<ul>) or something. Overall, it seems pretty logical.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jun 6 '16 at 2:49









                  Jamal

                  30.6k11121227




                  30.6k11121227










                  answered Jun 6 '16 at 1:20









                  TomanowTomanow

                  1214




                  1214























                      0












                      $begingroup$

                      Feedback



                      The code looks good so far. There appears to be good separation between the model, the view and the controller. I like how the model methods are concise - none more than 4 lines. The controller method _save_data() is a little on the lengthy side but hopefully the feedback below and in the answer by Tomanow will allow you to improve that method.



                      Suggestions



                      Regular expression



                      I agree with Tomanow's answer (except that you might not need to worry about stripping the pre-text, presuming that the pattern matching only matches country codes and names). A regular expression can be used in _save_data() to match each relevant row, and using a named sub-pattern, the code and name of each country can be selected:



                      $pattern = '/^'. //beginning of line
                      '(?P<country_code>[A-Za-z]2,4)'. // named sub-pattern for code: 2-4 alpha chars
                      's3'. //3 whitespace characters
                      '(?P<country_name>[A-Za-z()s.,'-]+)'. // named sub-pattern for name
                      '$/'; //end of line


                      If that pattern matches any rows, $matches['code'] will have the country code and $matches['name'] will have the country name. In theory, $matches could be sent to the insert_entry() model method, though that might be a weird design to accept the fields to insert directly (and the numeric indexes might need to be removed).



                      In theory the logic involving $startLine and $endLine can be removed by simply checking of the pattern matches.



                      $lines = file('http://pastebin.com/raw.php?i=943PQQ0n');
                      $pattern = '/^(?P<country_code>[A-Za-z]2,4)s3(?P<country_name>[A-Za-z()s.,'-]+)$/';

                      // Loop through our array, show HTML source as HTML source; and line numbers too.
                      foreach ($lines as $line_num => $line)
                      preg_match($pattern, $line, $matches);
                      if (count($matches))
                      $count = $this->country_model->count_by_code($matches['country_code']);
                      if (!$count)
                      $this->country_model->insert_entry($matches['country_code'], $matches['country_name']);





                      See a demonstration of the matching here in this playground example.



                      Useless variable $lineNo



                      In your method _save_data() there is a variable $lineNo that gets incremented each time. If you needed the count of each line, the variable $line_num (from the foreach statement) could be used instead (and added 1 to)...



                      foreach ($lines as $line_num => $line) {
                      $lineNo++;





                      share|improve this answer











                      $endgroup$

















                        0












                        $begingroup$

                        Feedback



                        The code looks good so far. There appears to be good separation between the model, the view and the controller. I like how the model methods are concise - none more than 4 lines. The controller method _save_data() is a little on the lengthy side but hopefully the feedback below and in the answer by Tomanow will allow you to improve that method.



                        Suggestions



                        Regular expression



                        I agree with Tomanow's answer (except that you might not need to worry about stripping the pre-text, presuming that the pattern matching only matches country codes and names). A regular expression can be used in _save_data() to match each relevant row, and using a named sub-pattern, the code and name of each country can be selected:



                        $pattern = '/^'. //beginning of line
                        '(?P<country_code>[A-Za-z]2,4)'. // named sub-pattern for code: 2-4 alpha chars
                        's3'. //3 whitespace characters
                        '(?P<country_name>[A-Za-z()s.,'-]+)'. // named sub-pattern for name
                        '$/'; //end of line


                        If that pattern matches any rows, $matches['code'] will have the country code and $matches['name'] will have the country name. In theory, $matches could be sent to the insert_entry() model method, though that might be a weird design to accept the fields to insert directly (and the numeric indexes might need to be removed).



                        In theory the logic involving $startLine and $endLine can be removed by simply checking of the pattern matches.



                        $lines = file('http://pastebin.com/raw.php?i=943PQQ0n');
                        $pattern = '/^(?P<country_code>[A-Za-z]2,4)s3(?P<country_name>[A-Za-z()s.,'-]+)$/';

                        // Loop through our array, show HTML source as HTML source; and line numbers too.
                        foreach ($lines as $line_num => $line)
                        preg_match($pattern, $line, $matches);
                        if (count($matches))
                        $count = $this->country_model->count_by_code($matches['country_code']);
                        if (!$count)
                        $this->country_model->insert_entry($matches['country_code'], $matches['country_name']);





                        See a demonstration of the matching here in this playground example.



                        Useless variable $lineNo



                        In your method _save_data() there is a variable $lineNo that gets incremented each time. If you needed the count of each line, the variable $line_num (from the foreach statement) could be used instead (and added 1 to)...



                        foreach ($lines as $line_num => $line) {
                        $lineNo++;





                        share|improve this answer











                        $endgroup$















                          0












                          0








                          0





                          $begingroup$

                          Feedback



                          The code looks good so far. There appears to be good separation between the model, the view and the controller. I like how the model methods are concise - none more than 4 lines. The controller method _save_data() is a little on the lengthy side but hopefully the feedback below and in the answer by Tomanow will allow you to improve that method.



                          Suggestions



                          Regular expression



                          I agree with Tomanow's answer (except that you might not need to worry about stripping the pre-text, presuming that the pattern matching only matches country codes and names). A regular expression can be used in _save_data() to match each relevant row, and using a named sub-pattern, the code and name of each country can be selected:



                          $pattern = '/^'. //beginning of line
                          '(?P<country_code>[A-Za-z]2,4)'. // named sub-pattern for code: 2-4 alpha chars
                          's3'. //3 whitespace characters
                          '(?P<country_name>[A-Za-z()s.,'-]+)'. // named sub-pattern for name
                          '$/'; //end of line


                          If that pattern matches any rows, $matches['code'] will have the country code and $matches['name'] will have the country name. In theory, $matches could be sent to the insert_entry() model method, though that might be a weird design to accept the fields to insert directly (and the numeric indexes might need to be removed).



                          In theory the logic involving $startLine and $endLine can be removed by simply checking of the pattern matches.



                          $lines = file('http://pastebin.com/raw.php?i=943PQQ0n');
                          $pattern = '/^(?P<country_code>[A-Za-z]2,4)s3(?P<country_name>[A-Za-z()s.,'-]+)$/';

                          // Loop through our array, show HTML source as HTML source; and line numbers too.
                          foreach ($lines as $line_num => $line)
                          preg_match($pattern, $line, $matches);
                          if (count($matches))
                          $count = $this->country_model->count_by_code($matches['country_code']);
                          if (!$count)
                          $this->country_model->insert_entry($matches['country_code'], $matches['country_name']);





                          See a demonstration of the matching here in this playground example.



                          Useless variable $lineNo



                          In your method _save_data() there is a variable $lineNo that gets incremented each time. If you needed the count of each line, the variable $line_num (from the foreach statement) could be used instead (and added 1 to)...



                          foreach ($lines as $line_num => $line) {
                          $lineNo++;





                          share|improve this answer











                          $endgroup$



                          Feedback



                          The code looks good so far. There appears to be good separation between the model, the view and the controller. I like how the model methods are concise - none more than 4 lines. The controller method _save_data() is a little on the lengthy side but hopefully the feedback below and in the answer by Tomanow will allow you to improve that method.



                          Suggestions



                          Regular expression



                          I agree with Tomanow's answer (except that you might not need to worry about stripping the pre-text, presuming that the pattern matching only matches country codes and names). A regular expression can be used in _save_data() to match each relevant row, and using a named sub-pattern, the code and name of each country can be selected:



                          $pattern = '/^'. //beginning of line
                          '(?P<country_code>[A-Za-z]2,4)'. // named sub-pattern for code: 2-4 alpha chars
                          's3'. //3 whitespace characters
                          '(?P<country_name>[A-Za-z()s.,'-]+)'. // named sub-pattern for name
                          '$/'; //end of line


                          If that pattern matches any rows, $matches['code'] will have the country code and $matches['name'] will have the country name. In theory, $matches could be sent to the insert_entry() model method, though that might be a weird design to accept the fields to insert directly (and the numeric indexes might need to be removed).



                          In theory the logic involving $startLine and $endLine can be removed by simply checking of the pattern matches.



                          $lines = file('http://pastebin.com/raw.php?i=943PQQ0n');
                          $pattern = '/^(?P<country_code>[A-Za-z]2,4)s3(?P<country_name>[A-Za-z()s.,'-]+)$/';

                          // Loop through our array, show HTML source as HTML source; and line numbers too.
                          foreach ($lines as $line_num => $line)
                          preg_match($pattern, $line, $matches);
                          if (count($matches))
                          $count = $this->country_model->count_by_code($matches['country_code']);
                          if (!$count)
                          $this->country_model->insert_entry($matches['country_code'], $matches['country_name']);





                          See a demonstration of the matching here in this playground example.



                          Useless variable $lineNo



                          In your method _save_data() there is a variable $lineNo that gets incremented each time. If you needed the count of each line, the variable $line_num (from the foreach statement) could be used instead (and added 1 to)...



                          foreach ($lines as $line_num => $line) {
                          $lineNo++;






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 5 mins ago

























                          answered Jan 9 '18 at 18:15









                          Sᴀᴍ OnᴇᴌᴀSᴀᴍ Onᴇᴌᴀ

                          10.6k62168




                          10.6k62168



























                              draft saved

                              draft discarded
















































                              Thanks for contributing an answer to Code Review Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              Use MathJax to format equations. MathJax reference.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f129657%2fsorting-a-list-by-country-name%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

                              格濟夫卡 參考資料 导航菜单51°3′40″N 34°2′21″E / 51.06111°N 34.03917°E / 51.06111; 34.03917ГезівкаПогода в селі 编辑或修订