1

I am working on a PHP MVC project for my portfolio. Its an web app where you can store contacts (email and phone number). I am having trouble with filtering contacts based on filter form that has 3 options https://ibb.co/8dJbSWd

I wrote code that works fine but i am sure there is better way of doing this. Here is the code that i wrote for solving this problem.

public function filterContacts($user_id, $group, $email, $phone){

        $query = 'SELECT * FROM contacts WHERE user_id = :user_id ';

        //Nothing is selected
        if($group == '0' && $email == '' && $phone == ''){

            $this->db->query($query . ' ORDER BY name');
            $this->db->bind(':user_id', $user_id);
            return $this->db->resultSet();

            //Everything is selected
        } else if ($group !== '0' && $email !== '' && $phone !== ''){

            $query .= 'AND contact_group = :group AND email != "" AND phone_number != ""';

            $this->db->query($query . 'ORDER BY name');
            $this->db->bind(':user_id', $user_id);
            $this->db->bind(':group', $group);

            return $this->db->resultSet();

            //Just group
        } else if ($group !== '0' && $email == '' && $phone == ''){

            $query .= 'AND contact_group = :group ';

            $this->db->query($query . 'ORDER BY name');
            $this->db->bind(':user_id', $user_id);
            $this->db->bind(':group', $group);

            return $this->db->resultSet();

            //Just email
        } else if ($group == '0' && $email !== '' && $phone == ''){

            $query .= 'AND email != "" ';

            $this->db->query($query . 'ORDER BY name');
            $this->db->bind(':user_id', $user_id);


            return $this->db->resultSet();

            //Just phone
        }  else if ($group == '0' && $email == '' && $phone !== ''){

            $query .= 'AND phone_number != "" ';

            $this->db->query($query . 'ORDER BY name');
            $this->db->bind(':user_id', $user_id);

            return $this->db->resultSet();

            //Group and email
        } else if($group !== '0' && $email !== '' && $phone == ''){

            $query .= 'AND contact_group = :group AND email != ""';

            $this->db->query($query . 'ORDER BY name');
            $this->db->bind(':user_id', $user_id);
            $this->db->bind(':group', $group);

            return $this->db->resultSet();

            //Group and phone number
        } else if($group !== '0' && $email == '' && $phone !== ''){
            $query .= 'AND contact_group = :group AND phone_number != ""';

            $this->db->query($query . 'ORDER BY name');
            $this->db->bind(':user_id', $user_id);
            $this->db->bind(':group', $group);

            return $this->db->resultSet();

            //Email and phone number
        } else if($group == '0' && $email !== '' && $phone !== ''){

            $query .= 'AND phone_number != "" AND email != ""';

            $this->db->query($query . 'ORDER BY name');
            $this->db->bind(':user_id', $user_id);

            return $this->db->resultSet();
        }

    }

As you can see i used a lot of if statements to make different queries in Contact model which is possible because i have only 3 filtering options but i cannot imagine doing this with 10 options.

So i was wondering is there a better way of solving this?

Here is link to my github repository if you want to see rest of the code https://github.com/Smiley-dev/Phonebook-demo

2
  • You should try codereview.stackexchange.com Commented Nov 26, 2019 at 15:54
  • I will. Thank you Commented Nov 26, 2019 at 16:11

1 Answer 1

1

You can use a class to do the heavy lifting for you and define what to do when some variable is set. This will help you get rid of the repeated code. Based off the code posted in your question something like this should get you going in the right direction.

QueryHelper.php

<?php
class QueryHelper
{
    function __construct($group, $email, $phone, $query, $db)
    {
        $this->_group = $group;
        $this->_email = $email;
        $this->_phone = $phone;
        $this->_query = $query;
        $this->_db = $db;

        $this->constructQuery();
    }

    private function constructQuery()
    {
       if($this->hasGroup())
       {
           $this->_query .= ' AND contact_group = :group';
       }

       if($this->hasEmail())
       {
           $this->_query .= ' AND email != ""';
       }

       if($this->hasPhone())
       {
           $this->_query .= ' AND phone_number != ""';
       }
    }

    public function UpdateBindings()
    {
        $this->_db->query($this->_query . ' ORDER BY name');

        if($this->hasGroup())
        {
            $this->_db->bind(':group', $group);
        }

        return $this->_db;
    }   

    private function hasGroup()
    {
         if ($this->_group !== '0')
         {
             return true;
         }
         else
         {
             return false;
         }
    }

    private function hasEmail()
    {
         if ($this->_email !== '')
         {
             return true;
         }
         else
         {
             return false;
         }
    }

    private function hasPhone()
    {
         if ($this->_phone !== '')
         {
             return true;
         }
         else
         {
             return false;
         }
    }

    private $_group;
    private $_email;
    private $_phone;
    private $_query;
    private $_db;
}

and file with function filterContacts()

include 'QueryHelper.php';
public function filterContacts($group, $email, $phone){
     $query = 'SELECT * FROM contacts WHERE user_id = :user_id ';
     $queryHelper = new QueryHelper($group, $email, $phone, $query, $this->db);
     $this->db = $queryHelper->UpdateBindings();
     $this->db->bind(':user_id', $user_id);

     return $this->db->resultSet();
}

You can add additional error checking and such but this should be a starting point for you.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.