Bulk name lookup for database relations

Overview

Tatter\Roster

Bulk name lookup for database relations in CodeIgniter 4

Coverage Status

Quick Start

  1. Install with Composer: > composer require tatter/roster
  2. Create a Roster class
  3. Load high-performance names: <?= service('roster')->user(1) ?>

Description

Roster solves a common, niche problem in an elegant way: quick access to display names for entity relations without requiring database lookup. An example... Your e-commerce app allows users to list their own products along with their username. To display the full product page, traditionally you would either need a database JOIN to fetch the usernames along with each product, or rely on a third-party solution like Object Relation Mapping (ORM) to load the related information. Roster simplifies and optimizes this by preloading batches of object names and caching them for convenient on-the-fly access.

Installation

Install easily via Composer to take advantage of CodeIgniter 4's autoloading capabilities and always be up-to-date:

  • > composer require tatter/roster

Or, install manually by downloading the source files and adding the directory to app/Config/Autoload.php.

Usage

The Roster service handles locating and interacting with your Roster classes, so all you need to do is create some Rosters. All Rosters must meet a few criteria to be discovered:

  • Rosters must extend the Base Roster (Tatter\Roster\BaseRoster)
  • Rosters must be located in a Rosters folder within a namespace (e.g. App\Rosters)
  • Rosters must be named by their lookup followed "Roster" (e.g. "CarRoster")

BaseRoster

BaseRoster defines the three methods that your class must implement:

  • protected function key(): string;
  • protected function fetchAll(): array;
  • protected function fetch($id): ?string;

See the BaseRoster file for more details.

ModelRoster

Most of the time Rosters will be fetching information from the database. In order to make this more convenient and reduce repetitive code this library comes with an intermediate support class, ModelRoster. If your Roster aligns with an existing Model then simply extend the ModelRoster class and supply these required fields:

  • protected $modelName;
  • protected $field;

Displaying

Once your Rosters are configured, use the service with the Roster name as the method and the ID of the item as the sole parameter:

$userName = service('roster')->user($userId);

Example

You are developing a blog. At the bottom of every post is a comments section where logged in users may post replies. Being the bright developer you are, you decide to use Tatter\Roster to handle the display and save on expensive database joins for every page.

First let's handle displaying the username next to each commet. You already have UserModel so we can use the ModelRoster to make it easier. Create app/Rosters/UserRoster.php:

namespace App\Rosters;

use App\Models\UserModel;
use Tatter\Roster\ModelRoster;

class UserRoster extends ModelRoster
{
	protected $modelName = UserModel::class;
	protected $field     = 'username';
}

That's it! ModelRoster handles retrieving the values based those properties. Now in our comment HTML block we can use the Roster service to display each username:

<?php foreach ($comments as $comment): ?>
<div class="comment">
    <blockquote><?= $comment->content ?></blockquote>
    <div class="comment-footer">
        Commented by <?= service('roster')->user($comment->user_id) ?>
    </div>
</div>
<?php endforeach; ?>

Let's do our blog tags next: under the post title we want to display each tag for this post. Unfortunately tags are in the format "[General] Specific" so no single field will work for the display. We can still use the ModelRoster but instead specifying the field we will provide our own determining method. Create app/Rosters/TagRoster.php:

namespace App\Rosters;

use App\Models\TagModel;
use Tatter\Roster\ModelRoster;

class TagRoster extends ModelRoster
{
    protected $modelName = TagModel::class;

    protected function getFieldValue(array $row): string
    {
        // Convert the database row from TagModel into its displayable form
        $general  = $row['general'];
        $specific = $row['specific'];

        return "[$general] $specific";
    }
}

Now our blog post header looks much cleaner:

<h1><?= $post->title ?></h1>
<div class="tags">
    <?php foreach ($post->tags as $tagId): ?>
    <span class="tag"><?= service('roster')->tag($tagId) ?></span>
    <?php endforeach; ?>
</div>

Finally, our blog is going to display a sidebar menu with post-relevant links to partners. This data will come from a third-party API, which would be an expensive call to make on every page load so we create a Roster for it. Because the data source is not a Model we need to make our own extension of the Base Roster. Create app/Rosters/LinkRoster.php:

namespace App\Rosters;

use App\Libraries\LinkApi;
use Tatter\Roster\BaseRoster;

class LinkRoster extends BaseRoster
{
    /**
     * Returns the handler-specific identifier used for caching
     */
    protected function key(): string
    {
        return 'roster-links';
    }

    /**
     * Loads all IDs and their names from the data source.
     */
    protected function fetchAll(): array
    {
        $results = [];
        $links   = new LinkApi();

        foreach ($links->list() as $link) {
            $results[$link->uid] = $link->href;
        }

        return $results;
    }

    /**
     * Loads a single ID and name from the data source.
     */
    protected function fetch($id): ?string
    {
        $links = new LinkApi();

        if ($link = $links->get($id)) {
            return $link->href;
        }

        return null;
    }
}

A little bit more code, but using BaseRoster gives a lot more control about where the data comes from and how it is formatted. You've probably already figure this part out, but let's finish off our links with their HTML menu:

<nav class="links-menu">
    <h3>Visit our partner blogs!</h3>
    <ul>
        <?php foreach ($post->partnerLinks as $uid): ?>
        <span class="tag"><?= service('roster')->link($uid) ?></span>
        <?php endforeach; ?>
    </ul>
</nav>
You might also like...
 Well secured MySQL Database Login and Registration with an seperate dashboard for consumers and admins.
Well secured MySQL Database Login and Registration with an seperate dashboard for consumers and admins.

WebApplicationPHP Well secured MySQL Database Login and Registration with an seperate dashboard for consumers and admins. Functions Well secured MySQL

A micro web application providing a REST API on top of any relational database, using Silex and Doctrine DBAL

Microrest is a Silex provider to setting up a REST API on top of a relational database, based on a YAML (RAML) configuration file.

🔐 Password Manager written in PHP with MySQL database.
🔐 Password Manager written in PHP with MySQL database.

Password Manager A very basic password manager. Tech stack: PHP MySQL Bootstrap Setup Download and install XAMPP. Clone this repository: git clone htt

A monthly payment report using HTML, CSS, PHP and MySQL database
A monthly payment report using HTML, CSS, PHP and MySQL database

A monthly payment report using HTML, CSS, PHP and MySQL database

Pico disk, Not need any database, support html5, support mp3, mp4, support streaming media, support AriaNg
Pico disk, Not need any database, support html5, support mp3, mp4, support streaming media, support AriaNg

Nano netdisk, Now changed to pico disk. Pico disk,does not need any database, support html5, support mp3, mp4, support streaming media, support AriaNg.

A simple web application that demonstrates how to quickly connect to and communicate with a MariaDB database using PHP
A simple web application that demonstrates how to quickly connect to and communicate with a MariaDB database using PHP

PHP Quickstart This repository contains a simple web application that demonstrates how to quickly connect to and communicate with a MariaDB database u

Create a PHP 8 CRUD (Create, Read, Update, Delete) RESTful API with an MySQL database.
Create a PHP 8 CRUD (Create, Read, Update, Delete) RESTful API with an MySQL database.

Créer une API RESTful PHP 8 CRUD (Create, Read, Update , Delete) simple avec MySQL et PDO (PHP Data Objects) Détails du référentiel : Lire, insérer, m

A Full Stack login/register system using a MySQL database to store the information
A Full Stack login/register system using a MySQL database to store the information

This is a Full Stack login/register system using a MySQL database to store the information. I created this to sharpen my Full Stack Development skills.

Database browser for the WoW Alpha Core project

Database browser for the WoW Alpha Core project

Comments
  • Bump actions/cache from 2 to 3.0.1

    Bump actions/cache from 2 to 3.0.1

    Bumps actions/cache from 2 to 3.0.1.

    Release notes

    Sourced from actions/cache's releases.

    v3.0.1

    • Added support for caching from GHES 3.5.
    • Fixed download issue for files > 2GB during restore.

    v3.0.0

    • This change adds a minimum runner version(node12 -> node16), which can break users using an out-of-date/fork of the runner. This would be most commonly affecting users on GHES 3.3 or before, as those runners do not support node16 actions and they can use actions from github.com via github connect or manually copying the repo to their GHES instance.

    • Few dependencies and cache action usage examples have also been updated.

    v2.1.7

    Support 10GB cache upload using the latest version 1.0.8 of @actions/cache

    v2.1.6

    • Catch unhandled "bad file descriptor" errors that sometimes occurs when the cache server returns non-successful response (actions/cache#596)

    v2.1.5

    • Fix permissions error seen when extracting caches with GNU tar that were previously created using BSD tar (actions/cache#527)

    v2.1.4

    • Make caching more verbose #650
    • Use GNU tar on macOS if available #701

    v2.1.3

    • Upgrades @actions/core to v1.2.6 for CVE-2020-15228. This action was not using the affected methods.
    • Fix error handling in uploadChunk where 400-level errors were not being detected and handled correctly

    v2.1.2

    • Adds input to limit the chunk upload size, useful for self-hosted runners with slower upload speeds
    • No-op when executing on GHES

    v2.1.1

    • Update @actions/cache package to v1.0.2 which allows cache action to use posix format when taring files.

    v2.1.0

    • Replaces the http-client with the Azure Storage SDK for NodeJS when downloading cache content from Azure. This should help improve download performance and reliability as the SDK downloads files in 4 MB chunks, which can be parallelized and retried independently
    • Display download progress and speed
    Changelog

    Sourced from actions/cache's changelog.

    3.0.1

    • Added support for caching from GHES 3.5.
    • Fixed download issue for files > 2GB during restore.
    Commits
    • 136d96b Enabling actions/cache for GHES based on presence of AC service (#774)
    • 7d4f40b Bumping up the version to fix download issue for files > 2 GB. (#775)
    • 2d8d0d1 Updated what's new. (#771)
    • 7799d86 Updated the usage and docs to the major version release. (#770)
    • 4b0cf6c Merge pull request #769 from actions/users/ashwinsangem/bump_major_version
    • 60c606a Update licensed files
    • b6e9a91 Revert "Updated to the latest version."
    • c842503 Updated to the latest version.
    • 2b7da2a Bumped up to a major version.
    • deae296 Merge pull request #651 from magnetikonline/fix-golang-windows-example
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 1
  • Bump actions/cache from 2 to 3

    Bump actions/cache from 2 to 3

    Bumps actions/cache from 2 to 3.

    Release notes

    Sourced from actions/cache's releases.

    v3.0.0

    • This change adds a minimum runner version(node12 -> node16), which can break users using an out-of-date/fork of the runner. This would be most commonly affecting users on GHES 3.3 or before, as those runners do not support node16 actions and they can use actions from github.com via github connect or manually copying the repo to their GHES instance.

    • Few dependencies and cache action usage examples have also been updated.

    v2.1.7

    Support 10GB cache upload using the latest version 1.0.8 of @actions/cache

    v2.1.6

    • Catch unhandled "bad file descriptor" errors that sometimes occurs when the cache server returns non-successful response (actions/cache#596)

    v2.1.5

    • Fix permissions error seen when extracting caches with GNU tar that were previously created using BSD tar (actions/cache#527)

    v2.1.4

    • Make caching more verbose #650
    • Use GNU tar on macOS if available #701

    v2.1.3

    • Upgrades @actions/core to v1.2.6 for CVE-2020-15228. This action was not using the affected methods.
    • Fix error handling in uploadChunk where 400-level errors were not being detected and handled correctly

    v2.1.2

    • Adds input to limit the chunk upload size, useful for self-hosted runners with slower upload speeds
    • No-op when executing on GHES

    v2.1.1

    • Update @actions/cache package to v1.0.2 which allows cache action to use posix format when taring files.

    v2.1.0

    • Replaces the http-client with the Azure Storage SDK for NodeJS when downloading cache content from Azure. This should help improve download performance and reliability as the SDK downloads files in 4 MB chunks, which can be parallelized and retried independently
    • Display download progress and speed
    Commits
    • 4b0cf6c Merge pull request #769 from actions/users/ashwinsangem/bump_major_version
    • 60c606a Update licensed files
    • b6e9a91 Revert "Updated to the latest version."
    • c842503 Updated to the latest version.
    • 2b7da2a Bumped up to a major version.
    • deae296 Merge pull request #651 from magnetikonline/fix-golang-windows-example
    • c7c46bc Merge pull request #707 from duxtland/main
    • 6535c5f Regenerated examples.md TOC
    • 3fdafa4 Update GitHub Actions status badge markdown in README.md
    • 341e6d7 Merge branch 'actions:main' into fix-golang-windows-example
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 1
  • Bump actions/checkout from 2 to 3

    Bump actions/checkout from 2 to 3

    Bumps actions/checkout from 2 to 3.

    Release notes

    Sourced from actions/checkout's releases.

    v3.0.0

    • Update default runtime to node16

    v2.4.0

    • Convert SSH URLs like org-<ORG_ID>@github.com: to https://github.com/ - pr

    v2.3.5

    Update dependencies

    v2.3.4

    v2.3.3

    v2.3.2

    Add Third Party License Information to Dist Files

    v2.3.1

    Fix default branch resolution for .wiki and when using SSH

    v2.3.0

    Fallback to the default branch

    v2.2.0

    Fetch all history for all tags and branches when fetch-depth=0

    v2.1.1

    Changes to support GHES (here and here)

    v2.1.0

    Changelog

    Sourced from actions/checkout's changelog.

    Changelog

    v2.3.1

    v2.3.0

    v2.2.0

    v2.1.1

    • Changes to support GHES (here and here)

    v2.1.0

    v2.0.0

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 1
Releases(v1.0.1)
  • v1.0.1(Mar 6, 2022)

    This release contains no content changes, but applies numerous coding style and readability updates.

    What's Changed

    • docs: highlight the source code in README by @kenjis in https://github.com/tattersoftware/codeigniter4-roster/pull/2
    • Update toolkit by @MGatner in https://github.com/tattersoftware/codeigniter4-roster/pull/3
    • Switch to Dev Kit by @MGatner in https://github.com/tattersoftware/codeigniter4-roster/pull/6
    • Bump actions/checkout from 2 to 3 by @dependabot in https://github.com/tattersoftware/codeigniter4-roster/pull/5

    New Contributors

    • @kenjis made their first contribution in https://github.com/tattersoftware/codeigniter4-roster/pull/2
    • @dependabot made their first contribution in https://github.com/tattersoftware/codeigniter4-roster/pull/5

    Full Changelog: https://github.com/tattersoftware/codeigniter4-roster/compare/v1.0.0...v1.0.1

    Source code(tar.gz)
    Source code(zip)
Owner
Tatter Software
Web app development for problem solving
Tatter Software
Database management in a single PHP file

Adminer - Database management in a single PHP file Adminer Editor - Data manipulation for end-users https://www.adminer.org/ Supports: MySQL, MariaDB

Jakub VrĂĄna 5.5k Jan 8, 2023
Bulit PHP Twitter Clone IN OOP style and using MYSQL Database.

Bulit PHP Twitter Clone IN OOP style and using MYSQL Database. AJAX and Jquery for requests without reloading like Follow/unfollow, like, Search users, Show popups like comment , User lists, etc.

Amin 47 Dec 3, 2022
Open Source Voucher Management System is a web application for manage voucher. used PHP with Laravel Framework and use MySQL for Database.

Voucher Management System is a web application for manage voucher. You can create and manage your voucher. Voucher Management System is used PHP with Laravel Framework and use MySQL for Database.

Artha Nugraha Jonar 34 Sep 17, 2022
Vote based Question & Answer site built using Laravel 5.4, material design, x-editable and jQuery Upvote with email and database notifications.

About Vote based Question & Answer site built using Laravel 5.4, material design, x-editable, jQuery Upvote and email/database notifications. Register

Jorge A. Gonzalez 116 Nov 2, 2022
Download Porn Adult XXX Videos Online Ready Site No Installation No Database Required

Download Porn Adult XXX Videos Online Ready Site No Installation No Database Required PHP / HTML How to USE Search Videos from any of the Supported Si

null 16 Apr 17, 2022
Vote based Question & Answer site built using Laravel 5.4, material design, x-editable and jQuery Upvote with email and database notifications.

About Vote based Question & Answer site built using Laravel 5.4, material design, x-editable, jQuery Upvote and email/database notifications. Register

Jorge A. Gonzalez 116 Nov 2, 2022
Simplified database records management.

Simplified database records management. Inspector will let you take care of CRUD without taking over your frontend. Example $inspector = new \InvoiceN

Invoice Ninja 6 Dec 17, 2022
Database version control, made easy!

Database version control, made easy! dbv.php is a database version control web application featuring schema management, revision scripts, and more! Ch

Victor Stanciu 1.7k Dec 9, 2022
Created simple login system and chat type website using mysql database along with php and html , css and javascript.

Created simple login system and chat type website using mysql database along with php and html , css and javascript.

null 1 Jan 6, 2022
An Online Movie Booking Website whose data is completely from a database

An Online Movie Booking Website whose data is completely from a database to ensure that it can be implemented in a real time scenario as any change of data needs to be done only in the database using SQL queries and the changes are immediately reflected.

Arunachalam M 7 Apr 13, 2022