Importing data from spreadsheet Not really an issue I am stuck on (the code works) but I just really don't like some code I wrote, if you're bored in lockdown maybe you might like to help.

Context:
I am import some data from a spreadsheet, it contains data about retail stores (grocery stores). As the data comes in from the spreadsheet, each row is stored as a StoreData object. Each store has upto five tills (point of sale devices) and I want the StoreData class to be able to return an array of information about each till. Here is the class showing the code relevant to the tills (the class is much bigger).

How can I clean up the function getTills()?


class StoreData
{
    private $spreadsheetData;

    private $tillModel;
    private $tillVersion;
    private $tillOneName;
    private $tillOneIpAddress;
    private $tillTwoName;
    private $tillTwoIpAddress;
    private $tillThreeName;
    private $tillThreeIpAddress;
    private $tillFourName;
    private $tillFourIpAddress;
    private $tillFiveName;
    private $tillFiveIpAddress;

    public function __construct($spreadsheetData, String $storeStatus)
    {
        $this-&gt;spreadsheetData = $spreadsheetData;
        $this-&gt;setStoreProperties();
    }

    private function setStoreProperties()
    {
        $this-&gt;tillModel = $this-&gt;spreadsheetData[17];
        $this-&gt;tillVersion = $this-&gt;spreadsheetData[7];
        $this-&gt;tillOneName = $this-&gt;spreadsheetData[40];
        $this-&gt;tillOneIpAddress = $this-&gt;spreadsheetData[41];
        $this-&gt;tillTwoName = $this-&gt;spreadsheetData[42];
        $this-&gt;tillTwoIpAddress = $this-&gt;spreadsheetData[43];
        $this-&gt;tillThreeName = $this-&gt;spreadsheetData[44];
        $this-&gt;tillThreeIpAddress = $this-&gt;spreadsheetData[45];
        $this-&gt;tillFourName = $this-&gt;spreadsheetData[46];
        $this-&gt;tillFourIpAddress = $this-&gt;spreadsheetData[47];
        $this-&gt;tillFiveName = $this-&gt;spreadsheetData[48];
        $this-&gt;tillFiveIpAddress = $this-&gt;spreadsheetData[49];
    }

    public function getTills()
    {
        $tillList = [];

        if ($this-&gt;tillOneName !== null)
        {
            $tillList[] = [
                'model' =&gt; $this-&gt;tillModel,
                'name' =&gt; $this-&gt;tillOneName,
                'ip_address' =&gt; $this-&gt;tillOneIpAddress,
                'version' =&gt; $this-&gt;tillVersion,
            ];
        }
        if ($this-&gt;tillTwoName !== null)
        {
            $tillList[] = [
                'model' =&gt; $this-&gt;tillModel,
                'name' =&gt; $this-&gt;tillTwoName,
                'ip_address' =&gt; $this-&gt;tillTwoIpAddress,
                'version' =&gt; $this-&gt;tillVersion,
            ];
        }
        if ($this-&gt;tillThreeName !== null)
        {
            $tillList[] = [
                'model' =&gt; $this-&gt;tillModel,
                'name' =&gt; $this-&gt;tillThreeName,
                'ip_address' =&gt; $this-&gt;tillThreeIpAddress,
                'version' =&gt; $this-&gt;tillVersion,
            ];
        }
        if ($this-&gt;tillFourName !== null)
        {
            $tillList[] = [
                'model' =&gt; $this-&gt;tillModel,
                'name' =&gt; $this-&gt;tillFourName,
                'ip_address' =&gt; $this-&gt;tillFourIpAddress,
                'version' =&gt; $this-&gt;tillVersion,
            ];
        }
        if ($this-&gt;tillFiveName !== null)
        {
            $tillList[] = [
                'model' =&gt; $this-&gt;tillModel,
                'name' =&gt; $this-&gt;tillFiveName,
                'ip_address' =&gt; $this-&gt;tillFiveIpAddress,
                'version' =&gt; $this-&gt;tillVersion,
            ];
        }
        return $tillList;
    }
}


For info, this is used to populate an eloquent model on a controller:

           foreach($storeData-&gt;getTills() as $till)
            {
                $store-&gt;tills()-&gt;create($till);
            }
You might want to create a service that accepts the spreadsheet data as method argument instead.

And maybe the columns could be configured to make it more flexible.

Also no need to do 5 times the same again, instead use a loop.

class SpreadsheetTillsConverter
{
  private int $modelColumn;
  private int $versionColumn;

  /** @var array&lt;int, int&gt; Map nameColumn =&gt; ipAddressColumn */
  private array $columns;

  public function __construct(int $modelColumn, int $versionColumn, array $columns)
  {
    $this-&gt;modelColumn = $modelColumn;
    $this-&gt;versionColumn = $versionColumn;
    $this-&gt;columns = $columns;
  }

  public function getTills(array $data): array
  {
     if (!isset($data[$this-&gt;modelColumn])) {
        throw new \InvalidArgumentException('Model column not found.');
     }
     $model = $data[$this-&gt;modelColumn];

     if (!isset($data[$this-&gt;versionColumn])) {
        throw new \InvalidArgumentException('Version column not found.');
     }
     $version = $data[$this-&gt;versionColumn];

     $result = [];
     foreach ($this-&gt;columns as $nameColumn =&gt; $ipAddressColumn) {
        if (isset($data[$nameColumn], $data[$ipAddressColumn])) {
          $result[] = [
            'model' =&gt; $model,
            'name' =&gt; $data[$nameColumn],
            'ip_address' =&gt; $data[$ipAddressColumn],
            'version' =&gt; $version,
          ];
        }
     }
     return $result;
  }
}

$converter = new SpreadsheetTillsConverter(17, 7, [
  40 =&gt; 41,
  42 =&gt; 43,
  44 =&gt; 45,
  46 =&gt; 47,
  48 =&gt; 49
]);

$tills = $converter-&gt;getTills($spreadsheetData);