php - Display the events for the current month first then the rest last desc

554

I have this controller which displays my events by event_date the date format is like 'Y-m-d'

Question Is there away that I could display the events for this month first in the list then the rest of the events after?

enter image description here

Model

public function getevents($filter = array()) {
    $this->db->limit($filter['limit'], $filter['start']);
    $this->db->order_by($filter['order'], $filter['sort']);
    $query = $this->db->get('event');
    return $query->result_array();
}

Controller

<?php

class Events extends Admin_Controller {

  private $error = array();

  public function __construct() {
    parent::__construct();
    $this->load->model('admin/event/events_model');
    $this->load->library("pagination");
  }

  public function index() {

    $this->getlist();
  }

  public function getlist() {

    $this->document->set_title('Events');

    $data['heading_title'] = 'Events';

    $data['breadcrumbs'] = array();

    $data['breadcrumbs'][] = array(
      'text' => 'Dashboard',
      'active' => '',
      'href' => site_url('admin/dashboard')
    );

    $data['breadcrumbs'][] = array(
      'text' => 'Events',
      'active' => 'active',
      'href' => site_url('admin/events')
    );

    if ($this->input->get('order')) {
      $order = $this->input->get('order'); 
    } else {
      $order = 'event_date';
    }

    if ($this->input->get('sort')) {
      $sort = $this->input->get('sort'); 
    } else {
      $sort = 'desc';
    }

    if ($this->input->get('limit')) {
      $limit = $this->input->get('limit'); 
    } else {
      $limit = 5;
    }

    if ($this->uri->segment(3)) {
      $page = $this->uri->segment(3); 
    } else {
      $page = 0;
    }

    $config["base_url"] = base_url('admin/events');
    $config["total_rows"] = $this->events_model->total_count();
    $config["per_page"] = $limit;
    $config["uri_segment"] = 3;
    $config['use_page_numbers'] = FALSE;

    $config['full_tag_open']  = '<nav><ul >';
    $config['full_tag_close']  = '</ul></nav>';
    $config['num_tag_open']   = '<li ><span >';
    $config['num_tag_close']  = '</span></li>';
    $config['cur_tag_open']   = '<li ><span >';
    $config['cur_tag_close']  = '<span >(current)</span></span></li>';
    $config['next_tag_open']  = '<li ><span >';
    $config['next_tagl_close'] = '<span aria-hidden="true">&raquo;</span></span></li>';
    $config['prev_tag_open']  = '<li ><span >';
    $config['prev_tagl_close'] = '</span></li>';
    $config['first_tag_open']  = '<li ><span >';
    $config['first_tagl_close'] = '</span></li>';
    $config['last_tag_open']  = '<li ><span >';
    $config['last_tagl_close'] = '</span></li>';

    $this->pagination->initialize($config);

    $filter = array(
      'order' => $order,
      'sort' => $sort,
      'limit' => $limit,
      'start' => $page 
    );

    $data['events'] = array();

    $events = $this->events_model->getevents($filter);
    foreach ($events as $event) {

      $button = array(
        'type' => 'button',
        'class' => 'btn btn-danger',
        'content' => '<i aria-hidden="true"></i> Remove',
        'data-toggle' => 'model',
        'data-target' => '#event_model',
        'data-id' => $event['event_id']
      );

      $data['events'][] = array(
        'event_title' => $event['event_title'],
        'event_date' => date('l dS F Y', strtotime($event['event_date'])),
        'href' => anchor('admin/events/update/' . $event['event_id'], 'Edit', array('class' => 'btn btn-primary')),
        'delete' => form_button($button)
      );
    }

    $data["pagination_links"] = $this->pagination->create_links();

    $data['header'] = Modules::run('admin/common/header/index');
    $data['column_left'] = Modules::run('admin/common/column_left/index');
    $data['footer'] = Modules::run('admin/common/footer/index');
    $data['topnavbar'] = Modules::run('admin/common/topnavbar/index');

    $this->load->view('template/event/getlist', $data);
  }
}
980

Answer

Solution:

uasort()

You don't need dedicated year and month table columns for this. Using native MySQL and PHP functions on date format, you can achieve almost any real world example algorithm. Here is what you should do to avoid unnecessary or overwhelming DB calls.

I assume that in this line

$events = $this->events_model->getevents($filter);

you are getting$events that could be something like this

$events = [
    0 => [
        'event_id' => 1,
        'event_date' => '2017-11-16',
    ],
    1 => [
        'event_id' => 2,
        'event_date' => '2017-02-22',
    ],
    2 => [
        'event_id' => 3,
        'event_date' => '2017-12-14',
    ],
    3 => [
        'event_id' => 4,
        'event_date' => '2017-11-16',
    ],
    4 => [
        'event_id' => 5,
        'event_date' => '2017-03-01',
    ],
    5 => [
        'event_id' => 6,
        'event_date' => '2017-12-02',
    ],
];

I didn't represent all fields but few needed for understanding principle

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Welcome extends CI_Controller
{

    public function index()
    {
        $events = [
            0 => [
                'event_id' => 1,
                'event_date' => '2017-11-16',
            ],
            1 => [
                'event_id' => 2,
                'event_date' => '2017-02-22',
            ],
            2 => [
                'event_id' => 3,
                'event_date' => '2017-12-14',
            ],
            3 => [
                'event_id' => 4,
                'event_date' => '2017-11-16',
            ],
            4 => [
                'event_id' => 5,
                'event_date' => '2017-03-01',
            ],
            5 => [
                'event_id' => 6,
                'event_date' => '2017-12-02',
            ],
        ];

        var_dump($events);

        // looping through an array cursor is moving forward 
        // so useing uasort, latest elements will be sorted closer to beginning
        // inversing array before uasort, rest of array keeps 
        // the order that is returned from db
        $events = array_reverse($events, $bool = false);// check yourself if you need true flag here

        try {
            uasort($events, array('self', 'cmp'));
        } catch (\Exception $e) {
            echo $e->getMessage();
        }

        var_dump($events);
    }

    public static function cmp($a)
    {
        $am = date('m', strtotime($a['event_date']));

        if ($am == date('m')) {
            return -1;
        }

        return 1;
    }

}

This should be the way of how you can sort elements by using child key in multidimensional array, and it is way better to use PHP for array operations than having multiple calls to database.

Also, PHP shows really great strength in work over arrays so you should consider using those functions and classes before making more DB calls than you actually need.

Edit:

Just got better resulst with this one:

var_dump($events);

$newArray = [];
foreach($events as $k => $v) {
    if (date('m', strtotime($v['event_date'])) == date('m')) {
        $newArray[] = $v;
        unset($events[$k]);
    }
}

var_dump(array_merge($newArray, $events));
exit;
174

Answer

Solution:

You could add$this->db->where('event_date >=', date('Y-m-01')); to yourgetevents() method, I guess.

942

Answer

Solution:

try replacing the following line of code:

    $this->db->order_by($filter['order'], $filter['sort']);

by the following line:

    $this->db->order_by("event_date", "desc");

And check if your event_date format is ok.

978

Answer

Solution:

Solution

I think just creating two arrays was the better option and then merge them. I had to create another column for a separate year and month

By adding the where() worked and or_where() then using array_merge

public function getevents($filter = array()) {

    $data1 = array();
    $data2 = array();

    $this->db->where('month =', date('m'));
    $this->db->order_by($filter['order'], $filter['sort']);
    $current_month_query = $this->db->get('event');

    foreach ($current_month_query->result_array() as $result1) {

        $data1[] = array(
            'event_title' => $result1['event_title'],
            'event_description' => $result1['event_description'],
            'event_date' => date('l dS F Y', strtotime($result1['event_date'])),
        );
    }

    $this->db->where('month >', date('m'));
    $this->db->or_where('month <', date('m'));
    $this->db->order_by($filter['order'], $filter['sort']);
    $other_query = $this->db->get('event');

    foreach ($other_query->result_array() as $result2) {

        $data2[] = array(
            'event_title' => $result2['event_title'],
            'event_description' => $result2['event_description'],
            'event_date' => date('l dS F Y', strtotime($result2['event_date'])),
        );
    }

    return array_merge($data1, $data2);
}

People are also looking for solutions to the problem: php - On load Edit page Image value be filled

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.