Skip to content

The Groups

The ODR software utilizes a number of group types:

The Lookup Value (LV) These groups take their options from a lookup table. Here is how one is defined in the backend:

php
namespace App\Services\App\Module\Specific\Ceramic;

class CeramicInitDetails implements InitDetailsInterface
{
    // ...
    public static function modelGroups(): array
    {
        return [
            // ...
            'Primary Classification' => [
                'code' => 'LV',
                'field_name' => 'ceramic_primary_classification_id',
                'lookup_table_name' => 'ceramic_primary_classifications',
                'lookup_text_field' => 'name',
                'dependency' => ['Scope.Artifact'],
            ],
        ];
    }
}

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

Module Tag (TM) These groups take their options from the module specific module_tags, restricted to a specific group (see ERD).

php
namespace App\Services\App\Module\Specific\Ceramic;

class CeramicInitDetails implements InitDetailsInterface
{
  // ...

  public static function modelGroups(): array
  {
      return [
        // ...
        'Vessel Base' => [
              'code' => 'TM',
              'dependency' => ['Vessel Part.Base'],
              'multiple' => true,
          ],
      ];
    }
}

As these groups represent optional properties, they are commonly dependent on other options.

The 'multiple' property functions as its name suggests.

TIP

Whether to implement a groups as a lookup or a tag is subjective. Use your judgement!

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)

Boolean Modified (BM) For lack of boolean support in MySql and in order to follow the lookup tables conventions, this group is defined with the following options (unsigned tinyInteger) - 0: Unassigned, 1: Unknown, 2: True, 3: False

The above groups define properties common to items in a module.

The following groups are used for filtering and defining dependencies:

Filter Only (FO) These groups typically consist of registration columns, or part of them. For example, small finds may have the following registration columns: locus_id, (registration) code, basket_no, artifact_no. where the locus_id is made of year + area + locus_no. In this case we may want to filter by Season, Area, and Registration Code:

php
namespace App\Services\App\Module\Specific\Ceramic;

class CeramicInitDetails implements InitDetailsInterface
{
  // ...
  public static function modelGroups(): array
  {
    return [
    // ...
    'Season' => [
                'code' => 'FO',
                'source' => ['module' => 'Season', 'field' => 'id'],
                'field_name' => 'locus_id',
                'manipulator' => function ($val) {
                    return (string) ($val + 10);
                },
            ],
            'Area' => [
                'code' => 'FO',
                'source' => ['module' => 'Area', 'field' => 'id'],
                'field_name' => 'area_id',
            ],
            'Registration Code' => [
                'code' => 'FO',
                'source' => ['module' => 'Ceramic', 'field' => 'code'],
                'field_name' => 'code',
            ],
        ];
  }
}

Categorized Groups (CG) These are used to manually define a discrete textual partition that may be dependent on multiple columns values. For example, we may want to define a “Registration Scope” group with the following options [Basket, Artifact] dependent on the condition artifact_no === 0.

In the backend we will implement the specific filter logic:

php
namespace App\Services\App\Module\Specific\Ceramic;

class CeramicReadDetails 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':
                    self::filterScope($group['selected']);
                    break;

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

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

        self::$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;
            }
        });
    }
}

Other filter groups are:

Column Search (CG) - Performs textual search on a specific column.

Order By (OB)

Media (MD) - Filter by existence of application-wide media types for an item

The implementation of the different filters can be found here.