Skip to content

Commit

Permalink
Merge pull request #1541 from cayb0rg/issue/1508-pagination
Browse files Browse the repository at this point in the history
Issue/1508 pagination
  • Loading branch information
clpetersonucf authored Feb 1, 2024
2 parents 6ebaef7 + 7598e84 commit ff99e23
Show file tree
Hide file tree
Showing 22 changed files with 516 additions and 263 deletions.
13 changes: 10 additions & 3 deletions fuel/app/classes/controller/api/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,20 @@ public function post_user($user_id)
return \Service_User::update_user($user_id, $user);
}

public function get_widget_search(string $input)
public function get_instance_search(string $input, string $page_number)
{
$input = trim($input);
$input = urldecode($input);
$page_number = (int) $page_number;
//no need to search if for some reason an empty string is passed
if ($input == '') return [];
return \Materia\Widget_Instance_Manager::get_search($input);
if ($input == '')
{
return [
'pagination' => [],
'next_page' => $page_number
];
}
return \Materia\Widget_Instance_Manager::get_paginated_instance_search($input, $page_number);
}

public function get_extra_attempts(string $inst_id)
Expand Down
40 changes: 28 additions & 12 deletions fuel/app/classes/materia/api/v1.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ static public function widget_instances_get($inst_ids = null, bool $deleted = fa
*
* @return array of objects containing total_num_pages and widget instances that are visible to the user.
*/
static public function widget_paginate_instances_get($page_number = 0)
static public function widget_paginate_user_instances_get($page_number = 0)
{
if (\Service_User::verify_session() !== true) return Msg::no_login();
$data = Widget_Instance_Manager::get_paginated_for_user(\Model_User::find_current_id(), $page_number);
$data = Widget_Instance_Manager::get_paginated_instances_for_user(\Model_User::find_current_id(), $page_number);
return $data;
}

Expand Down Expand Up @@ -886,23 +886,39 @@ static public function semester_date_ranges_get()
return Utils::get_date_ranges();
}

static public function users_search($search)
/**
* Paginated search for users that match input
*
* @param string Search query
* @param string Page number
* @return array List of users
*/
static public function users_search($input, $page_number = 0)
{
if (\Service_User::verify_session() !== true) return Msg::no_login();

$user_objects = \Model_User::find_by_name_search($search);
$user_arrays = [];
$items_per_page = 50;
$offset = $items_per_page * $page_number;

// query DB for only a single page + 1 item
$displayable_items = \Model_User::find_by_name_search($input, $offset, $items_per_page + 1);

$has_next_page = sizeof($displayable_items) > $items_per_page ? true : false;

if ($has_next_page) array_pop($displayable_items);

// scrub the user models with to_array
if (count($user_objects))
foreach ($displayable_items as $key => $person)
{
foreach ($user_objects as $key => $person)
{
$user_arrays[$key] = $person->to_array();
}
$displayable_items[$key] = $person->to_array();
}

return $user_arrays;
$data = [
'pagination' => $displayable_items,
];

if ($has_next_page) $data['next_page'] = $page_number + 1;

return $data;
}
/**
* Gets information about the current user
Expand Down
67 changes: 54 additions & 13 deletions fuel/app/classes/materia/widget/instance/manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ static public function get($inst_id, $load_qset=false, $timestamp=false, $delete
return count($instances) > 0 ? $instances[0] : false;
}

static public function get_all(Array $inst_ids, $load_qset=false, $timestamp=false, bool $deleted=false): array
static public function get_all(Array $inst_ids, $load_qset=false, $timestamp=false, bool $deleted=false, $offset=0, $limit=80): array
{
if ( ! is_array($inst_ids) || count($inst_ids) < 1) return [];

Expand All @@ -27,6 +27,9 @@ static public function get_all(Array $inst_ids, $load_qset=false, $timestamp=fal
->where('id', 'IN', $inst_ids)
->and_where('is_deleted', '=', $deleted ? '1' : '0')
->order_by('created_at', 'desc')
->order_by('id', 'desc')
->offset("$offset")
->limit("$limit")
->execute()
->as_array();

Expand Down Expand Up @@ -63,7 +66,7 @@ public static function get_all_for_user($user_id, $load_qset=false)
{
$inst_ids = Perm_Manager::get_all_objects_for_user($user_id, Perm::INSTANCE, [Perm::FULL, Perm::VISIBLE]);

if ( ! empty($inst_ids)) return Widget_Instance_Manager::get_all($inst_ids, $load_qset);
if ( ! empty($inst_ids)) return self::get_all($inst_ids, $load_qset);
else return [];
}

Expand All @@ -76,22 +79,25 @@ public static function get_all_for_user($user_id, $load_qset=false)
*
* @return array of widget instances that are visible to the user.
*/
public static function get_paginated_for_user($user_id, $page_number = 0)
public static function get_paginated_instances_for_user($user_id, $page_number = 0)
{
$inst_ids = Perm_Manager::get_all_objects_for_user($user_id, Perm::INSTANCE, [Perm::FULL, Perm::VISIBLE]);
$displayable_inst = self::get_all($inst_ids);
$widgets_per_page = 80;
$total_num_pages = ceil(sizeof($displayable_inst) / $widgets_per_page);
$offset = $widgets_per_page * $page_number;
$has_next_page = $offset + $widgets_per_page < sizeof($displayable_inst) ? true : false;

// inst_ids corresponds to a single page's worth of instances
$displayable_inst = array_slice($displayable_inst, $offset, $widgets_per_page);
$items_per_page = 80;
$offset = $items_per_page * $page_number;

// query DB for only a single page of instances + 1
$displayable_items = self::get_all($inst_ids, false, false, false, $offset, $items_per_page + 1);

// if the returned number of instances is greater than a page, there's more pages
$has_next_page = sizeof($displayable_items) > $items_per_page ? true : false;

if ($has_next_page) array_pop($displayable_items);

$data = [
'pagination' => $displayable_inst
'pagination' => $displayable_items
];

if ($has_next_page) $data['next_page'] = $page_number + 1;

return $data;
Expand Down Expand Up @@ -135,20 +141,55 @@ public static function lock($inst_id)
return $locked_by == $me;
}

/**
* Widget instance paginated search results
*
* @param input search input
* @param page_number page number
*
* @return array of items related to the given input
*/
public static function get_paginated_instance_search(string $input, $page_number = 0)
{
$items_per_page = 80;
$offset = $items_per_page * $page_number;

// query DB for only a single page of instances + 1
$displayable_items = self::get_widget_instance_search($input, $offset, $items_per_page + 1);

// if the returned number of instances is greater than a page, there's more pages
$has_next_page = sizeof($displayable_items) > $items_per_page ? true : false;

if ($has_next_page) array_pop($displayable_items);

$data = [
'pagination' => $displayable_items,
];

if ($has_next_page) $data['next_page'] = $page_number + 1;

return $data;
}

/**
* Gets all widget instances related to a given input, including id or name.
*
* @param input search input
* @param offset start search at this row in results
* @param limit number of rows to include
*
* @return array of widget instances related to the given input
*/
public static function get_search(string $input): array
public static function get_widget_instance_search(string $input, int $offset = 0, int $limit = 80): array
{
$results = \DB::select()
->from('widget_instance')
->where('id', 'LIKE', "%$input%")
->or_where('name', 'LIKE', "%$input%")
->order_by('created_at', 'desc')
->order_by('id', 'desc')
->offset($offset)
->limit($limit)
->execute()
->as_array();

Expand Down
14 changes: 11 additions & 3 deletions fuel/app/classes/model/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public static function find_by_username($username)
->get_one();
}

static public function find_by_name_search($name)
static public function find_by_name_search($name, $offset = 0, $limit=80)
{
$name = preg_replace('/\s+/', '', $name); // remove spaces

Expand All @@ -108,11 +108,19 @@ static public function find_by_name_search($name)
->or_where(\DB::expr('REPLACE(CONCAT(first, last), " ", "")'), 'LIKE', "%$name%")
->or_where('email', 'LIKE', "$name%")
->and_where_close()
->limit(50)
->offset($offset)
->limit($limit)
->as_object('Model_User')
->execute();

return $matches;
// convert object to array
$list = [];
foreach ($matches as $match)
{
$list[] = $match;
}

return $list;
}

public static function validate($factory)
Expand Down
53 changes: 36 additions & 17 deletions fuel/app/tests/api/v1.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,32 @@ public function test_widget_instances_get()

}

public function test_widget_paginate_instances_get()
public function test_widget_paginate_user_instances_get()
{
// Create widget instance
$this->_as_author();
$title = "My Test Widget";
$question = 'What rhymes with harvest fests but are half as exciting (or tasty)';
$answer = 'Tests';
$qset = $this->create_new_qset($question, $answer);
$widget = $this->make_disposable_widget();

$instance = Api_V1::widget_instance_new($widget->id, $title, $qset, true);

// ----- loads author's instances --------
$output = Api_V1::widget_paginate_user_instances_get();
$this->assertIsArray($output);
$this->assertArrayHasKey('pagination', $output);
foreach ($output['pagination'] as $key => $value)
{
$this->assert_is_widget_instance($value, true);
}

// ======= AS NO ONE ========
\Auth::logout();
// ----- returns no login --------
$output = Api_V1::widget_paginate_user_instances_get();
$this->assert_invalid_login_message($output);
}

public function test_widget_instance_new()
Expand Down Expand Up @@ -1024,10 +1047,6 @@ public function test_play_logs_get()

}

public function test_paginated_play_logs_get()
{
}

public function test_score_summary_get()
{
// ======= AS NO ONE ========
Expand Down Expand Up @@ -1522,10 +1541,10 @@ public function test_users_search_as_student()

$output = Api_V1::users_search('droptables');
$this->assertIsArray($output);
$this->assertCount(2, $output);
$this->assert_is_user_array($output[0]);
$this->assertFalse(array_key_exists('password', $output));
$this->assertFalse(array_key_exists('login_hash', $output));
$this->assertIsArray($output['pagination']);
$this->assert_is_user_array($output['pagination'][0]);
$this->assertFalse(array_key_exists('password', $output['pagination']));
$this->assertFalse(array_key_exists('login_hash', $output['pagination']));
}

public function test_users_search_as_author()
Expand All @@ -1538,10 +1557,10 @@ public function test_users_search_as_author()

$output = Api_V1::users_search('droptables');
$this->assertIsArray($output);
$this->assertCount(2, $output);
$this->assert_is_user_array($output[0]);
$this->assertFalse(array_key_exists('password', $output));
$this->assertFalse(array_key_exists('login_hash', $output));
$this->assertIsArray($output['pagination']);
$this->assert_is_user_array($output['pagination'][0]);
$this->assertFalse(array_key_exists('password', $output['pagination']));
$this->assertFalse(array_key_exists('login_hash', $output['pagination']));
}

public function test_users_search_as_super_user()
Expand All @@ -1554,10 +1573,10 @@ public function test_users_search_as_super_user()

$output = Api_V1::users_search('droptables');
$this->assertIsArray($output);
$this->assertCount(2, $output);
$this->assert_is_user_array($output[0]);
$this->assertFalse(array_key_exists('password', $output[0]));
$this->assertFalse(array_key_exists('login_hash', $output[0]));
$this->assertIsArray($output['pagination']);
$this->assert_is_user_array($output['pagination'][0]);
$this->assertFalse(array_key_exists('password', $output['pagination']));
$this->assertFalse(array_key_exists('login_hash', $output['pagination']));
}

protected function assert_is_semester_rage($semester)
Expand Down
Loading

0 comments on commit ff99e23

Please sign in to comment.