Jake Vanderwerf
2026-05-03 9bbeea742424837fb58207d88e10dbca0b2cae04
inc/managers/SEO/render/Traits/_Properties/offersTrait.php
@@ -1,9 +1,17 @@
<?php
namespace JVBase\managers\SEO\render\Traits\_Properties;
use JVBase\inc\managers\SEO\render\Thing\Intangible\ItemList\OfferCatalog;
use JVBase\managers\SEO\render\Thing\Intangible\Demand;
use JVBase\managers\SEO\render\Thing\Intangible\Offer;
use JVBase\managers\SEO\render\Thing\Intangible\Service;
use JVBase\managers\SEO\render\Thing\Intangible\StructuredValue\PriceSpecification;
use JVBase\managers\SEO\render\Thing\Product\Product;
use JVBase\managers\SEO\render\Traits\_Helpers\arrayHelper;
use JVBase\meta\Meta;
use JVBase\registrar\Fields;
use JVBase\registrar\Registrar;
use WP_Query;
if (!defined('ABSPATH')) {
   exit;
@@ -30,34 +38,155 @@
      }
      $this->offers = $offers;
   }
   public function getOpeningHoursFieldConfig():array
   public function setOffersField(Fields $fields):void
   {
      return [
      $fields->addField('generate_offers_from_content',
      [
         'type'   => 'true_false',
         'label'  => __('Generate Offers from Content', 'jvb'),
      ]);
      $fields->addField('seo_offers', [
         'type'   => 'repeater',
         'label'  => 'Opening Hours',
         'label'  => __('Offers', 'jvb'),
         'condition' => [
            'field'  => 'generate_offers_from_content',
            'value'  => true,
            'operator'  => '=='
         ],
         'fields' => [
            'dayOfWeek' => [
            'type'   => [
               'type'   => 'radio',
               'label'  => 'Day(s) of Week',
               'label'  => __('Select Type', 'jvb'),
               'options'   => [
                  'Mo'  => 'Monday',
                  'Tu'  => 'Tuesday',
                  'We'  => 'Wednesday',
                  'Th'  => 'Thursday',
                  'Fr'  => 'Friday',
                  'Sa'  => 'Saturday',
                  'Su'  => 'Sunday'
               ]
                  'product'   => 'Product',
                  'service'   => 'Service'
               ],
               'required' => true,
            ],
            'opens'  => [
               'type'   => 'time',
               'label'  => 'Opens At',
            'name'   => [
               'type'   => 'text',
               'label'  => __('Name of Product or Service', 'jvb'),
               'required'  => true,
            ],
            'closes' => [
               'type'   => 'time',
               'label'  => 'Closes At',
            'description'  => [
               'type'   => 'textarea',
               'label'  => __('Description (optional)', 'jvb'),
            ],
            'price'  => [
               'type'   => 'text',
               'subtype'   => 'number',
               'label'     => __('Price', 'jvb'),
            ],
            'unitText'  => [
               'type'   => 'radio',
               'label'  => 'Price per unit',
               'options'   => [
                  'hour'   => 'Hour',
                  'unit'   => 'Unit',
               ],
               'default'   => 'unit',
            ]
         ]
      ];
         ],
      ]);
   }
   public function formatOffersField(Meta $meta):void
   {
      $generate = $meta->get('generate_offers_from_content');
      if (!empty($generate) && $generate === true) {
         $this->generateOffersFromContent($meta);
         return;
      }
      $catalog = $meta->get('seo_offers');
      if (!empty($catalog)) {
         $offerCatalog = [];
         $name = '';
         $services = array_filter($catalog, function ($item) {
            return $item['type'] === 'service';
         });
         $products =array_filter($catalog, function ($item) {
            return $item['type'] === 'product';
         });
         if (count($products) > 0) {
            $name = 'Products';
            if (count($services) > 0) {
               $name .= ' & ';
            }
         }
         if (count($services) > 0) {
            $name .= 'Services';
         }
         foreach ($catalog as $row) {
            $offer = new Offer();
            $item = match($row['type']) {
               'product'   => new Product(),
               'service'   => new Service(),
            };
            $item->setName($row['name']);
            if (!empty($row['description'])) {
               $item->setDescription($row['description']);
            }
            if (!empty($row['price'])) {
               $price = new PriceSpecification();
               $price->setPrice($row['price']);
               $price->setPriceCurrency('CAD');
               $price->setUnitText($row['unitText']);
               $offer->setPriceSpecification($price);
            }
            $offer->setItemOffered($item);
            $offerCatalog[] =  $offer;
         }
         if (!empty(!$offerCatalog)) {
            $this->setOffers($offerCatalog);
         }
      }
   }
   /**
    * This presumes that the Meta instance being passed is for a profile content type.
    * @param Meta $meta
    * @return void
    */
   public function generateOffersFromContent(Meta $meta):void
   {
      $userID = (int)get_post_meta($meta->id(), BASE.'profile_link', true);
      if (empty($userID)) {
         return;
      }
      $user = get_userdata($userID);
      if (!$user) {
         return;
      }
      $registrar = Registrar::getInstance(jvbUserRole($userID));
      if (!$registrar) {
         return;
      }
      $types = $registrar->getCreatable();
      if (empty($types)) {
         return;
      }
      $offers = [];
      $cities = $meta->get('city');
      $rate = $meta->get('rate');
      $reviews = $meta->get('reviews');
      $rating = $meta->get('average_rating');
      $theCities = $theRate = $theReviews = $theRating = null;
      foreach($types as $type) {
         $based = jvbCheckBase($type);
         $hasAny = new WP_Query([
            'post_type'    => $based,
            'posts_per_page'=> 1,
            'fields'    => 'ids',
            'post_author'  => $userID
         ]);
         if ($hasAny->have_posts()) {
            $offer = new Offer();
            $typeRegistrar = Registrar::getInstance($type);
         }
      }
   }
}