Skip to content

The Groups

The Trio system utilizes a number of group types according to the group's required/optional, singular/multiple definitions and other limitations The software utilizes these group types:

The Lookup Value (LV) Group Type

These groups take their options from a lookup or a related table. In the case of a composite id, the reference key can be a subfield. Below are examples of both a "standard" foreign key (integer id) group, and a group references by a subfield, and their implementation in the back end of the Jezreel Expedition website:

php
class StoneGroups
{
    public static function getGroups(): array
    {
        return [
                //...
                'Primary Classification' => [
                'code' => 'LV',
                'fieldOrSubfield' => 'primary_classification_id',
                'lookup_table_name' => 'stone_primary_classifications',
                'lookup_text_field' => 'name',
                'lookup_order_by_field' => 'id',
                'useInTagger' => true,
                'showAsTag' => true,
                'dependency' => ['Scope:Artifact'],
            ],
        ]
    }
    //...
}

class CommonToFinds
{
     public static function getFindAreaGroup()
    {
        // All small find ids are a string of the form Season char(1) Area char(1) Locus number char(3)...
        return [
            'code' => 'LV',
            'fieldOrSubfield' => ['name' => 'locus_id', 'start' => 2, 'length' => 1], // SQL Base 1
            'lookup_table_name' => 'areas',
            'lookup_text_field' => 'id',
            'lookup_order_by_field' => 'id',
            'useInTagger' => false,
            'showAsTag' => false,
            'dependency' => [],
        ];
    }
}

By convention, the first two values in all "standard" lookup tables are 1: "Unassigned," 2: "Unknown"

Enum Fields (EM) Group Type

Much like the LV group type, the Enum group permits only a required/single selection. This group utilizes MySql's Enum column type which restricts possible values at the DB level.

Module Tag (TM) Group Type

Instances of this group store their options in the external [module]_tags and [module]_groups tables (see ERD).

php
class CeramicGroups
{
    public static function getGroups(): array
    {
        return [
        // ...
             'Ware Color' => [
                'code' => 'TM',
                'multiple' => true,
                'dependency' => [['Registration Scope:Artifact']],
            ],
      ];
    }
}

As these groups represent optional properties, they are commonly dependent upon other options. The 'multiple' property functions as its name suggests and that restiction is enforced at the front end applicaton level.

Global Tag (TG)

Similar in structure to the module tag group, these groups are common to multiple modules. The tables used to define and use them are:

  • tags
  • tag_groups
  • taggable (polymorphic pivot)

Optional Numeric Properties (ON) Group Type

These groups allow for the iclusion of numeric values to options selected. They are mostly used to represent optional measurements (e.g. bone measurements dependent on bone type) Their implementation is similar to that of the Module Tag group with an additional value column in the pivot table (see ERD).

Categorized Groups (CG) Group Type

These groups are used to design bespoke extrenious properties which are dependent on item's fields values. For example, we can define a “Registration Scope” group with the 'Basket' and 'Artifact' options. In this particular registration system we choose to define that the scope is 'Basket' if the artifact_no field value is zero, and 'Artifact' otherwise. The Categorized Groups type implement this logic by defining functions that 'choose' the correct category according to the given item's fields values.

Related functions are needed for both the back and front ends:

php
// Back end
class StoneReadDetails implements ReadDetailsInterface
{
    private static Builder $builder;

    public static function applyCategorizedFilters(Builder $builder, array $groups): Builder
    {
        self::$builder = $builder;

        foreach ($groups as $key => $group) {
            switch ($group['group_name']) {
                case 'Registration Scope':
                    static::filterScope($group['selected']);
                    break;

                default:
                    // Do nothing
            }
        }
        return self::$builder;
    }

    private static function filterScope(array $vals)
    {
        if (count($vals) !== 1) {
            return;
        }

        static::$builder->Where(function ($query) use ($vals) {
            switch ($vals[0]['name']) {
                case 'Basket':
                    $query->where('artifact_no', 0);
                    return;

                case 'Artifact':
                    $query->Where('artifact_no', '!=', 0);
                    return;

                default:
                    return;
            }
        });
    }
}
ts
// Front end
export const StoneConfigs: TModuleConfigs = {
  idRegExp:
    /^(?<season>[2-8])(?<area>[K-S])(?<locus_no>\d{3})(?<code>[A-Z]{2})(?<basket_no>\d{2})(?<artifact_no>\d{2})$/,

  //...
  categorizerFuncs: (fields?: TFields) => {
    const d = fields as TFields<"Stone">;
    return {
      "Registration Scope": d.id.substring(8) === "00" ? 0 : 1,
      // Index in the group's options array ['Basket', 'Artifact']
    };
  },
};

Group types used only as filters:

Field Search (FS)

These groups perform simple textual search on a specific field. Only OR operations between the different values are currently supported.

Order By (OB)

As the name suggests, these groups are used to order by specific columns or, in the case of "composite" fields, by a substring of the field.

Media (MD)

Filter by the existence of a related media type. Options correspond to the distinct values in the application-wide media.collection_name column.

The implementation of the different filters can be found here.

TIP

Choosing group types should be done cautiously and with user input. Any Open Dig Reports website can be used as an example.