Jake Vanderwerf
2026-07-05 fff721dd185f5b97f7ae7a6e64189e55887ff590
inc/registrar/Fields.php
@@ -1,11 +1,17 @@
<?php
namespace JVBase\registrar;
use JVBase\managers\SEO\render\Thing\Organization\LocalBusiness\LocalBusiness;
use JVBase\managers\SEO\render\Thing\Thing;
use JVBase\meta\Form;
use JVBase\meta\Meta;
use JVBase\registrar\fields\Field;
use JVBase\registrar\fields\GroupedField;
use JVBase\registrar\fields\OptionsField;
use JVBase\registrar\fields\TaxonomyField;
use JVBase\registrar\fields\Upload;
use JVBase\registrar\fields\RepeaterField;
use JVBase\registrar\fields\TagListField;
use JVBase\registrar\fields\SelectorField;
use JVBase\registrar\fields\UploadField;
if (!defined('ABSPATH')) {
   exit;
@@ -13,12 +19,17 @@
class Fields {
   protected array $fields;
   protected Registrar $registrar;
   private ?Registrar $registrar = null;
   protected ?string $type;
   public function __construct(?string $type = null, ?Registrar $registrar = null) {
      $this->registrar = $registrar;
      $this->type = $type;
      switch ($type) {
         case 'post':
            $this->addPostFields();
            //TODO: Add fields to post edit screen
//          add_action('add_meta_boxes', [$this, 'registerPostFields']);
            break;
         case 'term':
            $this->addTermFields();
@@ -27,26 +38,80 @@
            $this->addUserFields();
            break;
      }
      $this->registrar = $registrar;
   }
   public function addField(string $name, array $config):self {
      $this->fields[$name] = match ($config['type']) {
         'upload', 'image', 'gallery'  => new Upload($name, $config),
         'upload', 'image', 'gallery'  => new UploadField($name, $config),
         'checkbox', 'radio', 'select', 'set' => new OptionsField($name, $config),
         'repeater', 'group', 'tagList' => new GroupedField($name, $config),
         'selector', 'taxonomy', 'user', 'post' => new TaxonomyField($name, $config),
         'group' => new GroupedField($name, $config),
         'repeater'  => new RepeaterField($name, $config),
         'tagList'   => new TagListField($name, $config),
         'selector', 'taxonomy', 'user', 'post' => new SelectorField($name, $config),
         default => new Field($name, $config),
      };
      return $this;
   }
   public function addPostFields():void
   protected function defaultPostFields():array
   {
      $fields = [
      $statuses = [
//             'all' => [
//                'icon' => 'infinity',
//                'label' => 'Everything',
//             ],
         'publish' => [
            'icon' => 'eye',
            'label' => 'Live',
         ],
         'draft' => [
            'icon' => 'eye-closed',
            'label' => 'Hidden',
         ],
         'trash' => [
            'label' => 'Scrapped',
            'icon' => 'trash',
         ],
//       'delete' => [
//          'label'  => 'Permanently Delete',
//          'icon'   => 'trash'
//       ]
      ];
      if ($this->registrar->hasFeature('is_calendar')) {
         $statuses = [
            'future' => [
               'icon'   => '',
               'label'  => 'Upcoming',
            ],
            'past'   => [
               'icon'   => '',
               'label'  => 'Past',
            ],
            'repeat' => [
               'icon'   => '',
               'label'  => 'Repeating',
            ],
            'draft' => [
               'icon' => 'eye-closed',
               'label' => 'Hidden',
            ],
            'trash' => [
               'label' => 'Scrapped',
               'icon' => 'trash',
            ],
         ];
      }
      return [
         'post_status'  => [
            'type'      => 'radio',
            'label'     => 'Status',
            'default'   => 'draft',
            'options'   => $statuses
         ],
         'post_thumbnail'  => [
            'type'   => 'upload',
            'subtype'   => 'image',
            'multiple'=> false,
            'label'  => 'Main Image',
         ],
@@ -54,6 +119,11 @@
            'type'   => 'datetime',
            'label'  => 'Date',
         ],
         'post_modified' => [
            'type'   => 'datetime',
            'label'  => 'Date Modified',
            'hidden' => true,
         ],
         'post_content' => [
            'type'   => 'textarea',
            'quill'  => true,
@@ -69,41 +139,19 @@
            'label'  => 'TLDR',
            'maxLength' => 158,
         ],
         'post_status'  => [
            'type'      => 'radio',
            'label'     => 'Status',
            'default'   => 'draft',
            'options'   => [
               'all' => [
                  'icon' => 'infinity',
                  'label' => 'Everything',
               ],
               'publish' => [
                  'icon' => 'eye',
                  'label' => 'Live',
               ],
               'draft' => [
                  'icon' => 'eye-closed',
                  'label' => 'Hidden',
               ],
               'trash' => [
                  'label' => 'Scrapped',
                  'icon' => 'trash',
               ],
               'delete' => [
                  'label'  => 'Permanently Delete',
                  'icon'   => 'trash'
               ]
            ]
         ]
      ];
   }
   public function addPostFields():void
   {
      $fields = $this->defaultPostFields();
      foreach ($fields as $name => $config) {
         $this->addField($name, $config);
      }
   }
   public function addTermFields():void
   protected function defaultTermFields():array
   {
      $fields = [
         'name'   => [
@@ -117,57 +165,297 @@
            'label'     => 'Description',
         ]
      ];
      if ($this->registrar->registrar->hierarchical){
      if ($this->registrar->args()['hierarchical']??false){
         $fields['parent'] = [
            'type'         => 'taxonomy',
            'taxonomy_type'   => 'reference',
            'isReference'  => true,
            'autocomplete' => true,
            'label'        => 'Term Parent'
         ];
      }
      foreach ($fields as $name => $config) {
      return $fields;
   }
   public function addTermFields():void
   {
      foreach ($this->defaultTermFields() as $name => $config) {
         $this->addField($name, $config);
      }
   }
   public function addUserFields():void
   protected function defaultUserFields():array
   {
      $fields = [
      return [
         'first_name'   => [
            'type'   => 'text',
            'label'  => 'First Name',
            'section'=> 'your-account'
         ],
         'last_name' => [
            'type'   => 'text',
            'label'  => 'Last Name',
            'section'=> 'your-account'
         ],
         'user_email'   => [
            'type'   => 'email',
            'label'  => 'Your Email',
            'section'=> 'your-account'
         ],
         'display_name' => [
            'type'   => 'text',
            'label'  => 'Display Name',
            'section'=> 'your-account'
         ],
         'website'   => [
            'type'   => 'url',
            'label'  => 'Website',
         ],
         'description'  => [
            'type'   => 'textarea',
            'quill'  => true,
            'label'  => 'Description',
         ]
//       'website'   => [
//          'type'   => 'url',
//          'label'  => 'Website',
//       ],
//       'description'  => [
//          'type'   => 'textarea',
//          'quill'  => true,
//          'label'  => 'Description',
//       ],
      ];
      foreach ($fields as $name => $config) {
   }
   public function addUserFields():void
   {
      foreach ($this->defaultUserFields() as $name => $config) {
         $this->addField($name, $config);
      }
   }
   public function  modifyField(string $name, string $property, mixed $value):void
   {
      $property = 'set'.implode('',array_map('ucfirst',explode('_', $property)));
      $field = $this->fields[$name];
      $field->$property = $value;
      $field->$property($value);
   }
   public function getFields():array
   {
      return $this->fields;
   }
   public function addCommon(string $name):self
   {
      $method = 'add'.implode('',array_map('ucfirst',explode('_', $name))).'Field';
      if (method_exists($this, $method)) {
         $this->$method();
      } else {
         error_log('[Field]addCommon: No configuration found for '.$name.'.');
      }
      return $this;
   }
   protected function addWikiField(?string $label = null):void
   {
      $this->addField(
         'wiki',
         [
            'type'        => 'url',
            'label'       => $label ?: 'Wikipedia Page',
            'description' => 'For the schema',
            'quickEdit'   => true,
         ]
      );
   }
   protected function addLinksField(?string $label = null):void
   {
      $this->addField(
         'links',
         [
            'type'        => 'repeater',
            'quickEdit'   => true,
            'add_label' => 'title',
            'label'       => $label ?:'Online Links',
            'description' => 'These are listed publicly on the website',
            'fields'      => [
               'url'     => [
                  'type'  => 'url',
                  'label' => 'URL',
               ],
               'title'   => [
                  'type'  => 'text',
                  'label' => 'Label',
               ],
               'tracker' => [
                  'type'        => 'text',
                  'label'       => 'Tracker',
                  'description' => 'If you are set up to track link referrals, add what comes after the ? here.',
                  'default'      => 'ref=edmonton_ink'
               ],
            ],
            'section'     => 'contact'
         ]
      );
   }
   protected function addContactField():void
   {
      $this->addField(
         'admin_contact',
         [
            'type'      => 'set',
            'label'     => 'Admin Contact',
            'quickEdit' => true,
            'options'   => [
               'text'  => 'Text',
               'call'  => 'Call',
               'email' => 'Email',
               'insta' => 'Instagram',
            ],
            'section'   => 'contact'
         ]
      );
      $this->addField(
         'public_contact',
         [
            'type'      => 'set',
            'label'     => 'Public Contact',
            'quickEdit' => true,
            'options'   => [
               'text'  => 'Text',
               'call'  => 'Call',
               'email' => 'Email',
               'insta' => 'Instagram',
            ],
            'section'   => 'contact'
         ]
      );
   }
   protected function addReviewField(?string $label = null):void
   {
      $biz = new LocalBusiness();
      $biz->setReviewField($this);
   }
   protected function addAlternateNameField():void
   {
      $thing = new Thing();
      $thing->setAlternateNameField($this);
   }
   protected function addKeywordsField():void
   {
      $thing = new LocalBusiness();
      $thing->setKeywordsField($this);
   }
   protected function addOutsidePhotoField():void
   {
      $business = new LocalBusiness();
      $business->setPhotoField($this);
   }
   protected function addSloganField():void
   {
      $business = new LocalBusiness();
      $business->setSloganField($this);
   }
   protected function addPaymentField():void
   {
      $business = new LocalBusiness();
      $business->setPaymentAcceptedField($this);
   }
   protected function addAmenitiesField():void
   {
      $business = new LocalBusiness();
      $business->setAmenityFeatureField($this);
   }
   protected function addCredentialsField():void
   {
      $this->addField(
         'credentials',
         [
            'type'   => 'set',
            'label'  => __('Credentials', 'jvb'),
            'options'=> [
               'WHMIS 2015' => 'WHMIS 2015',
               'Tattoo and Piercing Safety Standards' => 'Tattoo and Piercing Safety Standards',
               'Bloodborne Pathogens and Infection Control' => 'Bloodborne Pathogens and Infection Control',
               'First Aid Training' => 'First Aid Training',
            ]
         ]
      );
   }
   protected function addPermanentlyCloseField():void
   {
      $business = new LocalBusiness();
      $business->setDissolutionDateField($this);
   }
   protected function addHoursField():void
   {
      $business = new LocalBusiness();
      $business->setOpeningHoursSpecificationField($this);
   }
   protected function addRateField():void
   {
      $this->addField('rate',
      [
         'type'   => 'text',
         'subtype'   => 'number',
         'label'     => __('Hourly Rate', 'jvb')
      ]);
   }
   protected function addAwardsField():void
   {
      $business = new LocalBusiness();
      $business->setAwardField($this);
   }
   protected function addRatingsField():void
   {
      $business = new LocalBusiness();
      $business->setAggregateRatingField($this);
   }
   protected function addServicesField():void
   {
      $business = new LocalBusiness();
      $business->setHasOfferCatalogField($this);
   }
   public function registerPostFields():void
   {
      $postType = $this->registrar->getBased();
      add_meta_box(
         $postType.'_fields',
         'Extra Fields',
         [$this, 'renderMyMetaBox'],
         $postType,
         'side',
         'high'
      );
   }
   public function renderMyMetaBox():void
   {
      $ID = get_the_ID();
      $meta = match ($this->type) {
         'post'   => Meta::forPost($ID),
         'term'   => Meta::forTerm($ID),
         'user'   => Meta::forUser($ID),
      };
      $defaults = array_keys(match($this->type) {
         'post'   => $this->defaultPostFields(),
         'term'   => $this->defaultTermFields(),
         'user'   => $this->defaultUserFields()
      });
      foreach ($this->fields as $fName => $field){
         if (!in_array($fName, $defaults)){
            echo Form::render($fName, $meta->get($fName),$field->getConfig());
         }
      }
   }
   public static function getUserFields():array
   {
      return (new self())->defaultUserFields();
   }
}