From 3cfc4a4664217abd9d76e59af636c2d664959527 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Fri, 28 Apr 2023 10:28:14 +0530 Subject: [PATCH 1/5] add site classification helper --- src/SiteClassification.php | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/SiteClassification.php diff --git a/src/SiteClassification.php b/src/SiteClassification.php new file mode 100644 index 0000000..ccde43b --- /dev/null +++ b/src/SiteClassification.php @@ -0,0 +1,42 @@ +fetch(); + set_transient( 'nfd_site_classification', $classification, DAY_IN_SECONDS ); + } + + return $classification; + } + + public function fetch() { + $classification = array(); + + $response = wp_remote_get( + NFD_HIIVE_BASE_URL . '/workers/site-classification', + array( + 'headers' => array( + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ), + ) + ); + + if ( ! is_wp_error( $response ) ) { + $body = wp_remote_retrieve_body( $response ); + $data = json_decode( $body, true ); + if ( $data && is_array( $data ) ) { + $classification = $data; + } + } + + return $classification; + } + +} From 874b868160f1b46e7b192606bd7a917eea2b0754 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Fri, 28 Apr 2023 10:32:38 +0530 Subject: [PATCH 2/5] define base Hiive url --- src/HiiveConnection.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/HiiveConnection.php b/src/HiiveConnection.php index 80756de..f5c1aa7 100644 --- a/src/HiiveConnection.php +++ b/src/HiiveConnection.php @@ -43,6 +43,11 @@ public function __construct() { define( 'NFD_HIIVE_URL', 'https://hiive.cloud/api' ); } + + if ( ! defined( 'NFD_HIIVE_BASE_URL' ) ) { + define( 'NFD_HIIVE_BASE_URL', 'https://hiive.cloud' ); + } + $this->api = NFD_HIIVE_URL; } From 9dc65a889aeb90f9e3e715e8146e7e183aaee1a5 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Fri, 28 Apr 2023 11:52:54 +0530 Subject: [PATCH 3/5] lint fixes --- src/HiiveConnection.php | 1 - src/SiteClassification.php | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/HiiveConnection.php b/src/HiiveConnection.php index f5c1aa7..5adaaa1 100644 --- a/src/HiiveConnection.php +++ b/src/HiiveConnection.php @@ -43,7 +43,6 @@ public function __construct() { define( 'NFD_HIIVE_URL', 'https://hiive.cloud/api' ); } - if ( ! defined( 'NFD_HIIVE_BASE_URL' ) ) { define( 'NFD_HIIVE_BASE_URL', 'https://hiive.cloud' ); } diff --git a/src/SiteClassification.php b/src/SiteClassification.php index ccde43b..3f6200d 100644 --- a/src/SiteClassification.php +++ b/src/SiteClassification.php @@ -2,7 +2,6 @@ namespace NewfoldLabs\WP\Module\Data; - class SiteClassification { public function get() { @@ -22,8 +21,8 @@ public function fetch() { NFD_HIIVE_BASE_URL . '/workers/site-classification', array( 'headers' => array( - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', ), ) ); From c3839b78fd53626a6e93faca053adced5ea731c6 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Fri, 28 Apr 2023 20:57:13 +0530 Subject: [PATCH 4/5] add better error handling, create a new HiiveWorker utility class --- src/HiiveConnection.php | 4 --- src/HiiveWorker.php | 58 +++++++++++++++++++++++++++++++++++++ src/SiteClassification.php | 59 +++++++++++++++++++++++++++----------- 3 files changed, 101 insertions(+), 20 deletions(-) create mode 100644 src/HiiveWorker.php diff --git a/src/HiiveConnection.php b/src/HiiveConnection.php index 5adaaa1..80756de 100644 --- a/src/HiiveConnection.php +++ b/src/HiiveConnection.php @@ -43,10 +43,6 @@ public function __construct() { define( 'NFD_HIIVE_URL', 'https://hiive.cloud/api' ); } - if ( ! defined( 'NFD_HIIVE_BASE_URL' ) ) { - define( 'NFD_HIIVE_BASE_URL', 'https://hiive.cloud' ); - } - $this->api = NFD_HIIVE_URL; } diff --git a/src/HiiveWorker.php b/src/HiiveWorker.php new file mode 100644 index 0000000..fee98a5 --- /dev/null +++ b/src/HiiveWorker.php @@ -0,0 +1,58 @@ +endpoint = $endpoint; + $this->url = NFD_HIIVE_BASE_URL . '/workers/' . $endpoint; + } + + /** + * Places an HTTP request to the Hiive CF worker. + * + * @param string $method The HTTP request method (GET, POST, ....). + * @param array $args The HTTP request arguments (headers, body, ...) + * @return array + */ + public function request( $method, $args ) { + $args['method'] = $method; + + return \wp_remote_request( + $this->url, + $args + ); + } +} diff --git a/src/SiteClassification.php b/src/SiteClassification.php index 3f6200d..562d93b 100644 --- a/src/SiteClassification.php +++ b/src/SiteClassification.php @@ -2,40 +2,67 @@ namespace NewfoldLabs\WP\Module\Data; +use NewfoldLabs\WP\Module\Data\HiiveWorker; + +/** + * Class SiteClassification + * + * Class that handles fetching and caching of site classification data. + * + * @package NewfoldLabs\WP\Module\Data + */ class SiteClassification { + /** + * Get site classification data. + * + * @return array + */ public function get() { + // Checks the transient for cached data. $classification = get_transient( 'nfd_site_classification' ); - if ( false === $classification ) { - $classification = $this->fetch(); + if ( false !== $classification ) { + return $classification; + } + + // Fetch data from the worker. + $classification = $this->fetch_from_worker(); + + // Cache the data if it is not empty. + if ( ! empty( $classification ) ) { set_transient( 'nfd_site_classification', $classification, DAY_IN_SECONDS ); } return $classification; } - public function fetch() { - $classification = array(); - - $response = wp_remote_get( - NFD_HIIVE_BASE_URL . '/workers/site-classification', + /** + * Fetch site classification data from the worker. + * + * @return array + */ + public function fetch_from_worker() { + $worker = new HiiveWorker( 'site-classification' ); + $response = $worker->request( + 'GET', array( 'headers' => array( - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', + 'Accept' => 'application/json', ), ) ); - if ( ! is_wp_error( $response ) ) { - $body = wp_remote_retrieve_body( $response ); - $data = json_decode( $body, true ); - if ( $data && is_array( $data ) ) { - $classification = $data; - } + if ( is_wp_error( $response ) || 200 !== \wp_remote_retrieve_response_code( $response ) ) { + return array(); } - return $classification; + $body = \wp_remote_retrieve_body( $response ); + $data = json_decode( $body, true ); + if ( ! $data || ! is_array( $data ) ) { + return array(); + } + + return $data; } } From 8820b8d598df47a53eaa5af3bef30d9d8fe72d86 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Tue, 9 May 2023 22:36:40 +0530 Subject: [PATCH 5/5] improve the site classification logic --- src/Data/Static/site-classification.json | 1 + src/SiteClassification.php | 68 ------------ src/SiteClassification/PrimaryType.php | 72 ++++++++++++ src/SiteClassification/SecondaryType.php | 79 ++++++++++++++ src/SiteClassification/SiteClassification.php | 103 ++++++++++++++++++ src/SiteClassification/Types.php | 96 ++++++++++++++++ 6 files changed, 351 insertions(+), 68 deletions(-) create mode 100644 src/Data/Static/site-classification.json delete mode 100644 src/SiteClassification.php create mode 100644 src/SiteClassification/PrimaryType.php create mode 100644 src/SiteClassification/SecondaryType.php create mode 100644 src/SiteClassification/SiteClassification.php create mode 100644 src/SiteClassification/Types.php diff --git a/src/Data/Static/site-classification.json b/src/Data/Static/site-classification.json new file mode 100644 index 0000000..4b71734 --- /dev/null +++ b/src/Data/Static/site-classification.json @@ -0,0 +1 @@ +{"author":"1856f1d57230c75ccb6553b17acc7a01","contentVersion":"0.0.3","parserVersion":"0.1.0","dataHash":"4e85c4fe94558d9af1e9c8e44fe0fa8f","types":{"business":{"slug":"business","label":"Business","icon":"https://cdn.hiive.space/site-classification/business.svg","emoji":"๐Ÿ’ผ","schema":"Corporation","secondaryTypes":{"agency-consulting":{"primaryType":"business","slug":"agency-consulting","label":"Agency & Consulting","emoji":"๐Ÿ’ก","wooType":"other","schema":"Organization","keywords":["expert","studio","strategy","management","innovation","biz","branding","growth","optimization","leadership"],"additionalPrimaryTypes":["personal","health-wellness"]},"arts-crafts":{"primaryType":"business","slug":"arts-crafts","label":"Arts & Crafts","emoji":"๐Ÿ–ผ๏ธ","wooType":"other","schema":"Organization","keywords":["painting","sculpture","mural","curation","auction","contemporary","modern","abstract","visual","exhibit"]},"autos-repair":{"primaryType":"business","slug":"autos-repair","label":"Autos & Repair","emoji":"๐Ÿš—","wooType":"other","schema":"AutomotiveBusiness","keywords":["car","mechanic","motorcycle","brakes","transmission","tires","parts","dealership","sales","tuning","detailing","bodywork","collision","restoration"]},"child-care":{"primaryType":"business","slug":"child-care","label":"Child Care","emoji":"๐Ÿ‘ถ","wooType":"education-and-learning","schema":"ChildCare","keywords":["babysit","nursery","infant","baby","toddler","camp","learning","preschool","daycare"]},"events":{"primaryType":"business","slug":"events","label":"Events","emoji":"๐ŸŽ‰","wooType":"food-drink","schema":"Organization","keywords":["corporate","holiday","conference","venue","rental","decor","AV","audio-visual","lighting","logistics","tickets","sponsorship","promotion","production","staffing"]},"finance":{"primaryType":"business","slug":"finance","label":"Finance","emoji":"๐Ÿ’ฐ","wooType":"other","schema":"Organization","keywords":["bank","planning","investment","mortgage","wealth","risk","credit","debt","cash","budget","accounting","tax","retirement","portfolio"]},"garden-florist":{"primaryType":"business","slug":"garden-florist","label":"Florist & Garden Center","emoji":"๐Ÿชด","wooType":"home-furniture-garden","schema":"Florist","keywords":["flowers","herbs","vegetable","soil","mulch"]},"hr-recruiting":{"primaryType":"business","slug":"hr-recruiting","label":"HR & Recruiting","emoji":"๐Ÿ‘ฉโ€๐Ÿ’ผ","wooType":"other","schema":"Organization","keywords":["human","resources","people","benefits","hiring","personnel","performance","onboarding","relocation","compliance","employee","HRIS","workforce","compensation","talent"]},"insurance":{"primaryType":"business","slug":"insurance","label":"Insurance","emoji":"๐Ÿ›ก๏ธ","wooType":"other","schema":"InsuranceAgency","keywords":["protection","life","liability","disability","compensation","umbrella","flood","pet","long-term care","marine"]},"legal":{"primaryType":"business","slug":"legal","label":"Legal","emoji":"โš–๏ธ","wooType":"other","schema":"Organization","keywords":["lawyer","attorney","estate","immigration","arbitration","mediation","contract","trademark","patent","civil","criminal","litigation"]},"marketing":{"primaryType":"business","slug":"marketing","label":"Marketing","emoji":"๐Ÿ“ข","wooType":"other","schema":"Organization","keywords":["promotion","SEO","advertising","social","content","digital","PPC","email","influencer","market","consumer","analytics","lead","sales","brand","loyalty"]},"outdoors":{"primaryType":"business","slug":"outdoors","label":"Outdoors","emoji":"๐Ÿ•๏ธ","wooType":"other","schema":"LocalBusiness","keywords":["hike","bike","hiking","biking","boat","swim","adventure","nature","wilderness","recreation","exploration","camping","fishing","hunting","climbing","kayak","raft","cycling","wildlife","scenic","sustainable","conservation","trail"]},"pr-communications":{"primaryType":"business","slug":"pr-communications","label":"PR & Communications","emoji":"โ˜Ž๏ธ","wooType":"other","schema":"Organization","keywords":["public","relations","crisis","spokesperson","reputation","internal","relations","affairs","publicity","media","press"]},"real-estate-management":{"primaryType":"business","slug":"real-estate-management","label":"Real Estate & Management","emoji":"๐Ÿ ","wooType":"other","schema":"LocalBusiness","keywords":["house","home","apartment","townhome","rental","mortgage","realtor","property","appraisal","brokerage","listings","inspections","staging"]},"shopping-retail":{"primaryType":"business","slug":"shopping-retail","label":"Shopping & Retail","emoji":"๐Ÿฌ","wooType":"other","schema":"Store","keywords":["commerce","brick-and-mortar","discounts","coupons","customer","product","loyalty","inventory","shipping","returns","cross-sell","upsell","gift cards"]},"trades-repair-services":{"primaryType":"business","slug":"trades-repair-services","label":"Trades & Repair Services","emoji":"๐Ÿ› ๏ธ","wooType":"home-furniture-garden","schema":"Organization","keywords":["plumbing","electrical","hvac","heating","cooling","AC","handy","locksmith","carpenter","flooring","pest control","cleaning","renovation","welding","masonry","garage","maintenance","roofing","painting"]},"weddings":{"primaryType":"business","slug":"weddings","label":"Weddings","emoji":"๐Ÿ’","wooType":"other","schema":"LocalBusiness","keywords":["bridal","dress","tuxedo","invitations","registry","ceremony","reception"]}}},"creative":{"slug":"creative","label":"Creative","icon":"https://cdn.hiive.space/site-classification/creative.svg","emoji":"๐ŸŽจ","schema":"Organization","secondaryTypes":{"artist":{"primaryType":"creative","slug":"artist","label":"Artist","emoji":"๐Ÿ–Œ๏ธ","wooType":"other","schema":"Person","keywords":["portraits","artwork","drawings","illustrations"]},"cosplay":{"primaryType":"creative","slug":"cosplay","label":"Cosplay","emoji":"๐Ÿฆธ","wooType":"fashion-apparel-accessories","schema":"Person","keywords":["costume","anime","manga","comics","fantasy","science","sci-fi","pop culture","props","wigs","makeup","fan","role-play","video games","character","fanart"]},"digital-creator":{"primaryType":"creative","slug":"digital-creator","label":"Digital Creator","emoji":"๐Ÿง‘โ€๐Ÿ’ป","wooType":"other","schema":"Person","keywords":["content","social","digital","youtube","podcast","blog","vlog","graphic","animation","virtual","VR","augmented","gaming","e-book"]},"influencer":{"primaryType":"creative","slug":"influencer","label":"Influencer","emoji":"๐ŸŽฅ","wooType":"other","schema":"Person","keywords":["collaboration","sponsored","audience","follower","instagram","youtube","tiktok","endorsement","affiliate","brand","consumer"]},"model":{"primaryType":"creative","slug":"model","label":"Model","emoji":"๐Ÿ‘—","wooType":"fashion-apparel-accessories","schema":"Person","keywords":["runway","catwalk","photoshoot","beauty","commercial","editorial","plus-size","glamour"]},"photogrpahy":{"primaryType":"creative","slug":"photogrpahy","label":"Photography","emoji":"๐Ÿ“ธ","wooType":"other","schema":"LocalBusiness","keywords":["aerial","stock","portrait","wildlife","documentary","street","equipment","lens"]},"writing":{"primaryType":"creative","slug":"writing","label":"Writing","emoji":"๐Ÿ“","wooType":"other","schema":"Person","keywords":["fiction","non-fiction","journalism","ghostwriting","proofreading","copywriting","script","freelance","academic","author","poetry","editing"]}}},"education":{"slug":"education","label":"Education","icon":"https://cdn.hiive.space/site-classification/education.svg","emoji":"๐Ÿ“š","schema":"EducationalOrganization","secondaryTypes":{"after-school":{"primaryType":"education","slug":"after-school","label":"After-School Programs","emoji":"๐Ÿ›","wooType":"education-and-learning","schema":"LocalBusiness","keywords":["enrichment","academic","tutoring","homework","STEM","lessons","life","character","mentoring","field trip","parent"]},"driving-schools":{"primaryType":"education","slug":"driving-schools","label":"Driving Schools","emoji":"๐Ÿ›ž","wooType":"education-and-learning","schema":"AutomotiveBusiness","keywords":["insurance","accident","traffic","DMV","RMV","highway","parallel","driving test","permit","license","behind-the-wheel","road","defensive","driver"]},"online-courses":{"primaryType":"education","slug":"online-courses","label":"Online Courses","emoji":"๐Ÿ’ป","wooType":"education-and-learning","schema":"EducationalOrganization","keywords":["e-learn","distance","virtual","MOOC","LMS","course","curriculum","interactive","lectures","webinars","self-paced","certifications","skill","knowledge","collaborative","test","assessment"]},"schools-universities":{"primaryType":"education","slug":"schools-universities","label":"Schools & Universities","emoji":"๐Ÿซ","wooType":"education-and-learning","schema":"School","keywords":["college","higher-ed","academic","student","admissions","financial aid","scholarship","campus","extracurricular","athletics","major","minor","faculty","research","alumni"]},"student-organization":{"primaryType":"education","slug":"student-organization","label":"Student Organizations","emoji":"๐Ÿ‘ฅ","wooType":"education-and-learning","schema":"Organization","keywords":["honor","debate","fraternity","sorority","student government","volunteer","music","theater","athletics","football","soccer","baseball","softball","volleyball","golf","community service","band","orchestra"]},"teacher":{"primaryType":"education","slug":"teacher","label":"Teacher","emoji":"๐Ÿง‘โ€๐Ÿซ","wooType":"education-and-learning","schema":"Person","keywords":["educator","pedagogy","learning","classroom"]},"test-preparation":{"primaryType":"education","slug":"test-preparation","label":"Test Preparation","emoji":"๐Ÿ—’๏ธ","wooType":"education-and-learning","schema":"Organization","keywords":["standardized","admissions","SAT","ACT","GRE","GMAT","LSAT","MCAT","test-taking","practice","scores","study","flashcards","private tutoring"]},"tutoring":{"primaryType":"education","slug":"tutoring","label":"Tutoring","emoji":"๐Ÿ“–","wooType":"education-and-learning","schema":"Organization","keywords":["test prep","academic","homework","learning","second-language","spanish","english","science","math","algebra","calculus","biology","chemistry","standardized","AP"]}}},"entertainment":{"slug":"entertainment","label":"Entertainment","icon":"https://cdn.hiive.space/site-classification/entertainment.svg","emoji":"๐Ÿ“บ","schema":"EntertainmentBusiness","secondaryTypes":{"comedy":{"primaryType":"entertainment","slug":"comedy","label":"Comedy","emoji":"๐Ÿคฃ","wooType":"other","schema":"EntertainmentBusiness","keywords":["stand-up","sketch","improv","satire","parody","humor","jokes","laugh","comedian","clubs","festivals","roast","prank","sitcom"]},"dance-theater":{"primaryType":"entertainment","slug":"dance-theater","label":"Dance & Theater","emoji":"๐ŸŽญ","wooType":"other","schema":"EntertainmentBusiness","keywords":["ballet","jazz","modern","tap dance","hip hop","contemporary","ballroom","chreography","playwriting","acting","stage"]},"film-tv":{"primaryType":"entertainment","slug":"film-tv","label":"Film & TV","emoji":"๐ŸŽฌ","wooType":"other","schema":"EntertainmentBusiness","keywords":["production","directing","cinematography","special effects","visual effects","sound design","reality","script","film","television"]},"gaming-e-sports":{"primaryType":"entertainment","slug":"gaming-e-sports","label":"Gaming & E-sports","emoji":"๐ŸŽฎ","wooType":"other","schema":"EntertainmentBusiness","keywords":["tournaments","game engine","PC","console","VR","multiplayer","streaming","shooter"]},"live-events":{"primaryType":"entertainment","slug":"live-events","label":"Live Events","emoji":"๐ŸŽŸ๏ธ","wooType":"other","schema":"EntertainmentBusiness","keywords":["concerts","trade show","exhibition","launch","award","charity","fairs","rallies","ceremonies","weddings","game","match","meetup"]},"music":{"primaryType":"entertainment","slug":"music","label":"Music","emoji":"๐ŸŽต","wooType":"other","keywords":["open-mic","instrument","recording","theory","genre","playlist","vocal","guitar","brass","woodwind","percussion","drum","jazz","blues","marching",""]},"publishing-media":{"primaryType":"entertainment","slug":"publishing-media","label":"Publishing & Media","emoji":"๐Ÿ“ฐ","wooType":"other","keywords":["book","author","journalism","media","magazine","writing","editing"]},"radio-podcasts":{"primaryType":"entertainment","slug":"radio-podcasts","label":"Radio & Podcasts","emoji":"๐Ÿ“ป","wooType":"other","keywords":["broadcast","talk show","voiceover","host","storytelling","audiobook"]},"talent-management":{"primaryType":"entertainment","slug":"talent-management","label":"Talent Management","emoji":"๐Ÿง‘โ€๐Ÿ’ผ","wooType":"other","keywords":["acting","talent","representation","casting","audition","hollywood","guild","union","scout","headshots","reels"]},"video-streaming":{"primaryType":"entertainment","slug":"video-streaming","label":"Video & Streaming","emoji":"๐Ÿ“น","wooType":"other","schema":"EntertainmentBusiness","keywords":["youtube","vimeo","vlog","reaction","DIY","reviews","travel","cooking","challenges","influencer","subscribe"]}}},"fashion-beauty":{"slug":"fashion-beauty","label":"Fashion & Beauty","icon":"https://cdn.hiive.space/site-classification/fashion-beauty.svg","emoji":"๐Ÿ’…","schema":"HealthAndBeautyBusiness","secondaryTypes":{"accessories":{"primaryType":"fashion-beauty","slug":"accessories","label":"Accessories","emoji":"โŒš๏ธ","wooType":"fashion-apparel-accessories","keywords":["watches","hats","sunglasses","scarves","belts","handbags","wallets","backpacks","ties","bowtie","gloves","socks","boots","sandals","sneakers","shoes"]},"clothing":{"primaryType":"fashion-beauty","slug":"clothing","label":"Clothing","emoji":"๐Ÿ‘•","wooType":"fashion-apparel-accessories","keywords":["denim","dresses","jeans","sweaters","activewear","lingerie","formal","second-hand","consignment"]},"fragrances":{"primaryType":"fashion-beauty","slug":"fragrances","label":"Fragrances","emoji":"๐ŸŒผ","wooType":"fashion-apparel-accessories","keywords":["perfume","cologne","aromatherapy","floral","woody","oils","diffusers","gift","parfum","toilette","citrus","tees","t-shirt","apparel"]},"haircare":{"primaryType":"fashion-beauty","slug":"haircare","label":"Haircare","emoji":"๐Ÿ’ˆ","wooType":"health-beauty","keywords":["styling","extensions","color","haircut","scalp","blow-dry","curling","flat iron","hair loss"]},"jewelry":{"primaryType":"fashion-beauty","slug":"jewelry","label":"Jewelry","emoji":"๐Ÿ’Ž","wooType":"fashion-apparel-accessories","keywords":["rings","necklaces","earrings","bracelets","precious","semi-precious","pearl","gem","birthstone","band","allergy","gold","silver","bronze","steel"]},"makeup-skincare":{"primaryType":"fashion-beauty","slug":"makeup-skincare","label":"Makeup & Skincare","emoji":"๐Ÿ’„","wooType":"fashion-apparel-accessories","keywords":["cosmetics","facial","moisturize","serum","toner","foundation","blush","mascara","eyeliner","lipstick","sunscreen","acne","concealer","deodorent"]},"nailcare":{"primaryType":"fashion-beauty","slug":"nailcare","label":"Nailcare","emoji":"๐Ÿ’…","wooType":"health-beauty","keywords":["polish","salon","manicure","pedicure","gel","acrylic","extensions","cuticle","french"]},"shoes":{"primaryType":"fashion-beauty","slug":"shoes","label":"Shoes","emoji":"๐Ÿ‘Ÿ","wooType":"fashion-apparel-accessories","keywords":["boots","running","hiking","dress","casual","heels","flats","loafers","wedges","slippers"]},"stylists":{"primaryType":"fashion-beauty","slug":"stylists","label":"Stylists","emoji":"๐Ÿ’ƒ","wooType":"fashion-apparel-accessories","keywords":["wardrobe","trends","fashion","beauty","image","personal"]},"tattoos-piercings":{"primaryType":"fashion-beauty","slug":"tattoos-piercings","label":"Tattoos & Piercings","emoji":"๐Ÿชก","wooType":"health-beauty","keywords":["parlor","geometric","tribal","sleeve","back","chest","removal","body","ear","nose","lip","tongue","navel","cartilage","septum","studs","hoops","barbells","dermal"]}}},"food-beverage":{"slug":"food-beverage","label":"Food & Beverage","icon":"https://cdn.hiive.space/site-classification/food-beverage.svg","emoji":"๐Ÿ•","schema":"FoodService","secondaryTypes":{"bakeries":{"primaryType":"food-beverage","slug":"bakeries","label":"Bakeries","emoji":"๐Ÿฅ","wooType":"food-drink","schema":"Bakery","keywords":["cake","cupcake","donuts","bagels","pie","bread","baguette","desserts","sourdough"]},"bars":{"primaryType":"food-beverage","slug":"bars","label":"Bars","emoji":"๐Ÿป","wooType":"food-drink","schema":"BarOrPub","keywords":["cocktail","craft","wine","mixology","liquor","spirits","pub","dive bar","speakeasy","DJ","karaoke","nightlife","bottle service","bartender","barkeep","margarita","bourbon","club"]},"catering":{"primaryType":"food-beverage","slug":"catering","label":"Catering","emoji":"๐Ÿฑ","wooType":"food-drink","schema":"FoodEstablishment","keywords":["event","corporate","party","wedding","buffet","plated","family-style","menu","vegetarian","kosher","farm-to-table"]},"chefs":{"primaryType":"food-beverage","slug":"chefs","label":"Chefs","emoji":"๐Ÿง‘โ€๐Ÿณ","wooType":"food-drink","schema":"FoodEstablishment","keywords":["culinary","gourmet","restaurant","kitchen","cooking","pastry","sous","fusion","gastronomy","ethnic"]},"coffee-tea":{"primaryType":"food-beverage","slug":"coffee-tea","label":"Coffee & Tea","emoji":"โ˜•๏ธ","wooType":"food-drink","schema":"FoodEstablishment","keywords":["espresso","cappuccino","latte","cold brew","herbal","loose-leaf","beans","roasting","brew","speciality","single-origin"]},"farms":{"primaryType":"food-beverage","slug":"farms","label":"Farms","emoji":"๐Ÿง‘โ€๐ŸŒพ","wooType":"food-drink","schema":"Organization","keywords":["dairy","agriculture","crop","livestock","sustainable","organic","CSA","irrigation","fertilizer","harvest","tractor","soil","citrus","vegetable"]},"food-trucks":{"primaryType":"food-beverage","slug":"food-trucks","label":"Food Trucks","emoji":"๐Ÿšš","wooType":"food-drink","schema":"FoodEstablishment","keywords":["mobile","street food","gourmet","sandwiches","tacos","burger","bbq","barbeque","seafood","vegetarian","vegan","festival"]},"grocers-markets":{"primaryType":"food-beverage","slug":"grocers-markets","label":"Grocers & Markets","emoji":"๐Ÿ›’","wooType":"food-drink","schema":"GroceryStore","keywords":["supermarket","farmer's market","local","meat","seafood","deli","bakery","produce","frozen","snacks","prepared","condiments","health"]},"recipes":{"primaryType":"food-beverage","slug":"recipes","label":"Recipes","emoji":"๐Ÿ“‹","wooType":"food-drink","schema":"Blog","keywords":["one-pot","breakfast","lunch","dinner","cooking","baking","entrees","appetizers","snacks","healthy","quick","weeknight"]}}},"government-politics":{"slug":"government-politics","label":"Government & Politics","icon":"https://cdn.hiive.space/site-classification/government-politics.svg","emoji":"๐Ÿ›๏ธ","schema":"Organization","secondaryTypes":{"activism-advocacy":{"primaryType":"government-politics","slug":"activism-advocacy","label":"Activism & Advocacy","emoji":"๐Ÿชง","wooType":"other","keywords":["justice","civil","human","grassroots","philanthropy","lobbying","volunteer","healthcare","rights","LGBT","racial"]},"emergency-relief":{"primaryType":"government-politics","slug":"emergency-relief","label":"Emergency Relief","emoji":"๐Ÿ›Ÿ","wooType":"other","keywords":["disaster","response","humanitarian","aid","crisis","preparedness","rescue","humanitarian","shlter","response","community"]},"judiciary":{"primaryType":"government-politics","slug":"judiciary","label":"Judiciary","emoji":"๐Ÿง‘โ€โš–๏ธ","wooType":"other","keywords":["court","appeal","trial","judge"]},"law-enforcement":{"primaryType":"government-politics","slug":"law-enforcement","label":"Law Enforcement","emoji":"๐Ÿšจ","wooType":"other","keywords":["police","justice","forensic","homeland","border","traffic","SWAT","k-9","intelligence","surveillance","crime","investigation","detective","officer"]},"libraries":{"primaryType":"government-politics","slug":"libraries","label":"Libraries","emoji":"๐Ÿ“š","wooType":"education-and-learning","keywords":["public","books","newspaper","research","reference","literacy","wifi"]},"military-veterans":{"primaryType":"government-politics","slug":"military-veterans","label":"Military & Veterans","emoji":"๐Ÿช–","wooType":"other","keywords":["armed","army","navy","air force","marines","national guard","reserves","deployment","VA","PTSD","transition"]},"policy-campaigns":{"primaryType":"government-politics","slug":"policy-campaigns","label":"Policy & Campaigns","emoji":"๐Ÿ—ณ๏ธ","wooType":"other","keywords":["grassroots","public opinion","messaging","fundraising","political action committee","PAC","election"]},"politicians":{"primaryType":"government-politics","slug":"politicians","label":"Politicians","emoji":"๐Ÿ‡บ๐Ÿ‡ณ","wooType":"other","keywords":["president","minister","governor","senator","represensitive","mayor","council","assembly","parliment","secretary","ambassador","consul","administrator"]},"public-services":{"primaryType":"government-politics","slug":"public-services","label":"Public Services","emoji":"๐Ÿ”Œ","wooType":"other","schema":"GovernmentService","keywords":["public works","waste management","parks","recreation","police","fire","water","sewer","housing","street","sidewalk","parking","code enforcement","permits","inspections","zoning","transit","transport"]},"towns-cities-regions":{"primaryType":"government-politics","slug":"towns-cities-regions","label":"Towns/Cities/Regions","emoji":"๐Ÿ—บ๏ธ","wooType":"other","schema":"AdministrativeArea","keywords":["city","county","state","municipalities","local","infrastructure","taxes","permits","tourism","public health","regulation","social"]}}},"health-wellness":{"slug":"health-wellness","label":"Health & Wellness","icon":"https://cdn.hiive.space/site-classification/health-wellness.svg","emoji":"โš•๏ธ","schema":"HealthAndBeautyBusiness","secondaryTypes":{"agency-consulting":{"primaryType":"business","slug":"agency-consulting","label":"Agency & Consulting","emoji":"๐Ÿ’ก","wooType":"other","schema":"Organization","keywords":["expert","studio","strategy","management","innovation","biz","branding","growth","optimization","leadership"],"additionalPrimaryTypes":["personal","health-wellness"]},"counseling-mental-health":{"primaryType":"health-wellness","slug":"counseling-mental-health","label":"Counseling & Mental Health","emoji":"๐Ÿง ","wooType":"health-beauty","keywords":["therapy","depression","anxiety","stress","trauma","grief","substance","addition","abuse","disorder","relationship","mindfulness","meditation","wellness"]},"dentist-ortho":{"primaryType":"health-wellness","slug":"dentist-ortho","label":"Dentist & Ortho","emoji":"๐Ÿฆท","wooType":"health-beauty","keywords":["hygiene","cleaning","whitening","braces","invisalign","retainers","implants","crowns","fillings","root canal","oral surgery","wisdom teeth"]},"doctor":{"primaryType":"health-wellness","slug":"doctor","label":"Doctor","emoji":"๐Ÿฉบ","wooType":"health-beauty","keywords":["medicine","health","care","general","practitioner","specialist","cardiologist","dermotologist","endocrinologist","neurologist","oncologist","cancer","pediatrician","psychiatrist","surgeon","allergist"]},"gym":{"primaryType":"health-wellness","slug":"gym","label":"Gym","emoji":"๐Ÿ’ช","wooType":"health-beauty","keywords":["fitness","group","weight loss","muscle","cardio","strength","yoga","pilates","crossfit","bodybuilding","weight","treadmill","elliptical","interval"]},"nutrition-weight-loss":{"primaryType":"health-wellness","slug":"nutrition-weight-loss","label":"Nutrition & Weight Loss","emoji":"๐Ÿฅ•","wooType":"health-beauty","keywords":["diet","health","nutrients","calorie","portion","superfood","planning","vegan","vegetarian","gluten","carb","fat","intermittent","keto","supplements","detox","metabolism"]},"physical-therapist":{"primaryType":"health-wellness","slug":"physical-therapist","label":"Physical Therapist","emoji":"๐Ÿฆต","wooType":"health-beauty","keywords":["orthopedic","sports","pediatric","geriatric","aquatic","injury","chronic","balance","surgery"]},"retreats":{"primaryType":"health-wellness","slug":"retreats","label":"Retreats","emoji":"๐Ÿง˜","wooType":"health-beauty","keywords":["yoga","meditation","mindfulness","spiritual","detox","ayurvedic","holistic","couples","silent","beach","mountain"]},"spas":{"primaryType":"health-wellness","slug":"spas","label":"Spas","emoji":"๐Ÿ›€","wooType":"health-beauty","keywords":["massage","facial","aromatherapy","relaxation","hot stone","deep tissue","sweedish","reflexology","waxing","sauna","jacuzzi"]},"spirituality":{"primaryType":"health-wellness","slug":"spirituality","label":"Spirituality","emoji":"โ›ช๏ธ","wooType":"health-beauty","keywords":["christianity","islam","hindu","buddhism","bahรก'รญ","energy","reiki","chakra","zen","enlightenment","transcendence"]},"trainer":{"primaryType":"health-wellness","slug":"trainer","label":"Trainer","emoji":"๐Ÿ‹๏ธ","wooType":"health-beauty","keywords":["exercise","flexibility","core","resistance","functional","endurance","wellness"]}}},"nonprofit":{"slug":"nonprofit","label":"Nonprofit","icon":"https://cdn.hiive.space/site-classification/nonprofit.svg","emoji":"โค๏ธ","schema":"Organization","secondaryTypes":{"animals-wildlife":{"primaryType":"nonprofit","slug":"animals-wildlife","label":"Animals & Wildlife","emoji":"๐Ÿถ","wooType":"other","keywords":["shelter","rescue","adoption","foster","humane","stray","spay","neuter","pet"]},"civic-community-groups":{"primaryType":"nonprofit","slug":"civic-community-groups","label":"Civic & Community Groups","emoji":"๐Ÿ‘ฅ","wooType":"other","keywords":["nonprift","grassroots","philanthropy","donate","neighborhood","outreach","town hall","coalition"]},"climate-environment":{"primaryType":"nonprofit","slug":"climate-environment","label":"Climate & Environment","emoji":"๐ŸŒฒ","wooType":"other","keywords":["greenhouse","carbon","global warming","footprint","energy","clean","crisis","fossil","deforestation","biodiversity","ocean"]},"diversity-equity-inclusion":{"primaryType":"nonprofit","slug":"diversity-equity-inclusion","label":"Diversity, Equity & Inclusion","emoji":"๐ŸŸฐ","wooType":"other","keywords":["black","african","immigrant","women","LGBT","gay","lesbian","trans","bias","intersectionality","discrimination","ally","unconscious","racism","multiculturalism","aggression"]},"foundations":{"primaryType":"nonprofit","slug":"foundations","label":"Foundations","emoji":"๐Ÿซถ","wooType":"other","keywords":["welfare","youth","rights","arts","culture","faith","charity"]},"military-veterans":{"primaryType":"nonprofit","slug":"military-veterans","label":"Military & Veterans","emoji":"๐ŸŽ–๏ธ","wooType":"other","keywords":["armed","army","navy","air force","marines","national guard","reserves","deployment","VA","PTSD","transition"]},"museums":{"primaryType":"nonprofit","slug":"museums","label":"Museums","emoji":"๐Ÿ–ผ๏ธ","wooType":"other","keywords":["art","exhibit","science","children","cultural","aviation","war","botanical","acquariam","planetarium","zoo","collection"]},"religious-groups":{"primaryType":"nonprofit","slug":"religious-groups","label":"Religious Groups","emoji":"โ›ช๏ธ","wooType":"other","keywords":["christianity","islam","hindu","buddhism","bahรก'รญ","energy","reiki","chakra","zen","enlightenment","transcendence"]},"trade-professional-groups":{"primaryType":"nonprofit","slug":"trade-professional-groups","label":"Trade & Professional Groups","emoji":"๐Ÿง‘โ€โœˆ๏ธ","wooType":"other","schema":"Organization","keywords":["organization","association","industry","business","chamber","commerce","networking","standards","market","leadership"]}}},"personal":{"slug":"personal","label":"Personal","icon":"https://cdn.hiive.space/site-classification/personal.svg","emoji":"๐Ÿ‘ฉ","schema":"Person","secondaryTypes":{"agency-consulting":{"primaryType":"business","slug":"agency-consulting","label":"Agency & Consulting","emoji":"๐Ÿ’ก","wooType":"other","schema":"Organization","keywords":["expert","studio","strategy","management","innovation","biz","branding","growth","optimization","leadership"],"additionalPrimaryTypes":["personal","health-wellness"]},"art":{"primaryType":"personal","slug":"art","label":"Art","emoji":"๐ŸŽจ","wooType":"other","keywords":["expression","artistic","scrapbook","printmaking","calligraphy","drawing","painting","sculpture","pottery"]},"blog":{"primaryType":"personal","slug":"blog","label":"Blog","emoji":"๐Ÿง‘โ€๐Ÿ’ป","wooType":"other","keywords":["lifestyle","food","fashion","travel","beauty","DIY","parenting","technology","career","finance","politics","news"]},"creative-portfolio":{"primaryType":"personal","slug":"creative-portfolio","label":"Creative Portfolio","emoji":"๐Ÿ’ผ","wooType":"other","keywords":["art","design","photo","fashion","film","video","tv","music","writing","architecture","interior design","UX","UI","web design","web engineering","app design","VFX","creative"]},"digital-creator":{"primaryType":"personal","slug":"digital-creator","label":"Digital Creator","emoji":"๐Ÿง‘โ€๐ŸŽจ","wooType":"other","keywords":["youtuber","podcaster","twitch","instagrammer","tiktok","social media","marketer","author","designer","developer","animator","creator"]},"influencer":{"primaryType":"personal","slug":"influencer","label":"Influencer","emoji":"๐Ÿ˜Ž","wooType":"other","keywords":["youtuber","podcaster","twitch","instagrammer","tiktok","social media","marketer","author","designer","developer","animator","creator"]},"model":{"primaryType":"personal","slug":"model","label":"Model","emoji":"๐Ÿ’ƒ","wooType":"other","keywords":["runway","catwalk","photoshoot","beauty","commercial","editorial","plus-size","glamour"]},"photography":{"primaryType":"personal","slug":"photography","label":"Photography","emoji":"๐Ÿ“ธ","wooType":"other","keywords":["aerial","stock","portrait","wildlife","documentary","street","equipment","lens"]},"wedding":{"primaryType":"personal","slug":"wedding","label":"Wedding","emoji":"๐Ÿ’","wooType":"other","keywords":["bridal","dress","tuxedo","invitations","registry","ceremony","reception"]},"writing":{"primaryType":"personal","slug":"writing","label":"Writing","emoji":"๐Ÿ“","wooType":"other","keywords":["fiction","non-fiction","journalism","ghostwriting","proofreading","copywriting","script","freelance","academic","author","poetry","editing"]}}},"startup":{"slug":"startup","label":"Startup","icon":"https://cdn.hiive.space/site-classification/startup.svg","emoji":"๐Ÿš€","schema":"Organization","secondaryTypes":[]},"tech":{"slug":"tech","label":"Tech","icon":"https://cdn.hiive.space/site-classification/tech.svg","emoji":"๐Ÿ’ป","schema":"Organization","secondaryTypes":{"agency-consulting":{"primaryType":"tech","slug":"agency-consulting","label":"Agency & Consulting","emoji":"๐Ÿ’ก","wooType":"electronics-computers","schema":"Organization","keywords":["expert","studio","strategy","management","innovation","biz","branding","growth","optimization","leadership"]},"apps-software":{"primaryType":"tech","slug":"apps-software","label":"Apps & Software","emoji":"๐Ÿ’พ","wooType":"electronics-computers","schema":"Organization","keywords":["productivity","social media","entertainment","gaming","navigation","communication","messaging","editing","dating","ride-hailing","carshare","budget","amazon","ebay"]},"blockchain":{"primaryType":"tech","slug":"blockchain","label":"Blockchain","emoji":"โ›“๏ธ","wooType":"electronics-computers","schema":"Organization","keywords":["crypto","bitcoin","DeFI","smart contract","proof of work","tokenization","decentralize","identity"]},"edutech":{"primaryType":"tech","slug":"edutech","label":"Edutech","emoji":"๐Ÿ–ฅ๏ธ","wooType":"education-and-learning","schema":"Organization","keywords":["LMS","MOOC","learning","gamification","virtual","augmented","personalized","textbook","video-based","e-learning-microlearning","assessment","test"]},"fintech":{"primaryType":"tech","slug":"fintech","label":"Fintech","emoji":"๐Ÿ’ณ","wooType":"electronics-computers","schema":"Organization","keywords":["banking","payments","wallets","peer-to-peer","P2P","crypto","blockchain","lending","insurtech","wealthtech","regtech","fraud","credit"]},"hardware-wearables":{"primaryType":"tech","slug":"hardware-wearables","label":"Hardware & Wearables","emoji":"โŒš๏ธ","wooType":"electronics-computers","schema":"Organization","keywords":["computers","laptops","tablets","smartphones","headphones","console","TV","soundbar","thermostat","security","drone","3D printer","robotics"]},"services-saas":{"primaryType":"tech","slug":"services-saas","label":"Services (Saas)","emoji":"โš™๏ธ","wooType":"electronics-computers","schema":"Organization","keywords":["CRM","project","management","marketing","automation","drop-ship","time track","CMS","LMS","cybersecurity","payment","invoicing","collaboration","helpdesk","support","email"]},"social-communities":{"primaryType":"tech","slug":"social-communities","label":"Social Networks & Communities","emoji":"๐Ÿ‘ฅ","wooType":"electronics-computers","schema":"Organization","keywords":["forums","peer-to-peer","support","dating","crowdsourcing","hobby","DIY","job boards","online"]}}},"travel-tourism":{"slug":"travel-tourism","label":"Travel & Tourism","icon":"https://cdn.hiive.space/site-classification/travel-tourism.svg","emoji":"โœˆ๏ธ","schema":"Organization","secondaryTypes":{"attractions":{"primaryType":"travel-tourism","slug":"attractions","label":"Attractions","emoji":"๐ŸŽข","wooType":"other","schema":"TouristAttraction","keywords":["theme parks","museums","landmark","beach","waterfall","zoo","wildlife","park","botanical","arena","stadium","vineyard","bungee"]},"hotels-lodging":{"primaryType":"travel-tourism","slug":"hotels-lodging","label":"Hotels & Lodging","emoji":"๐Ÿ›๏ธ","wooType":"other","keywords":["motel","hotel","bed and breakfast","B&B","resort","villa","condo","cottage","cabin","houseboat","treehouse","turn","lodge","campsite","camping","RV"]},"property-management":{"primaryType":"travel-tourism","slug":"property-management","label":"Property Management","emoji":"๐Ÿ™๏ธ","wooType":"other","keywords":["HOA","condo","lease","short-term","homestay","guesthouse","apartment","condo","cabin","yurt","ranch","island"]},"rentals":{"primaryType":"travel-tourism","slug":"rentals","label":"Rentals","emoji":"๐Ÿ›ต","wooType":"other","keywords":["homes","apartments","villas","condos","cabins","cottages","yurt","RV's","campervans","hostels","bike","boat","kyak","scooter","moped","motorcycle","car","offroad","watercraft","snowmobile","ski","snowboard","surfboard","scuba","golf club","tents"]},"tours-guides":{"primaryType":"travel-tourism","slug":"tours-guides","label":"Tours & Guides","emoji":"๐Ÿ“˜","wooType":"other","keywords":["walking","city","cultural","history","historical","adventure","safari","scuba","snorkeling","ecotourism","wine","art","ghost","helicopter","zipline"]},"travel-agency":{"primaryType":"travel-tourism","slug":"travel-agency","label":"Travel Agency","emoji":"๐Ÿง‘โ€๐Ÿ’ผ","wooType":"other","keywords":["budget","solo","road trip","backpacking","family","adventure","luxury","glamping","deals","discounts","hotel","bed and breakfast","airbnb"]},"travel-influencer":{"primaryType":"travel-tourism","slug":"travel-influencer","label":"Travel Influencer","emoji":"๐Ÿ๏ธ","wooType":"other"}}},"other":{"slug":"other","label":"Other","icon":"https://cdn.hiive.space/site-classification/other.svg","emoji":"๐ŸŒŽ","schema":"Thing","secondaryTypes":[]}}} \ No newline at end of file diff --git a/src/SiteClassification.php b/src/SiteClassification.php deleted file mode 100644 index 562d93b..0000000 --- a/src/SiteClassification.php +++ /dev/null @@ -1,68 +0,0 @@ -fetch_from_worker(); - - // Cache the data if it is not empty. - if ( ! empty( $classification ) ) { - set_transient( 'nfd_site_classification', $classification, DAY_IN_SECONDS ); - } - - return $classification; - } - - /** - * Fetch site classification data from the worker. - * - * @return array - */ - public function fetch_from_worker() { - $worker = new HiiveWorker( 'site-classification' ); - $response = $worker->request( - 'GET', - array( - 'headers' => array( - 'Accept' => 'application/json', - ), - ) - ); - - if ( is_wp_error( $response ) || 200 !== \wp_remote_retrieve_response_code( $response ) ) { - return array(); - } - - $body = \wp_remote_retrieve_body( $response ); - $data = json_decode( $body, true ); - if ( ! $data || ! is_array( $data ) ) { - return array(); - } - - return $data; - } - -} diff --git a/src/SiteClassification/PrimaryType.php b/src/SiteClassification/PrimaryType.php new file mode 100644 index 0000000..26e4261 --- /dev/null +++ b/src/SiteClassification/PrimaryType.php @@ -0,0 +1,72 @@ +refers ) { + return true; + } + + // Retrieve the data to validate. + $classification = SiteClassification::get(); + // Checks if the value is a valid primary type slug. + if ( ! isset( $classification['types'] ) || ! isset( $classification['types'][ $this->value ] ) ) { + return false; + } + + return true; + } + + /** + * Instantiates a class object from the data stored in the option. + * + * @return PrimaryType|boolean + */ + public static function instantiate_from_option() { + $data = get_option( self::$primary_option_name, false ); + + if ( ! $data || ! is_array( $data ) || ! isset( $data['refers'] ) || ! isset( $data['value'] ) ) { + delete_option( self::$primary_option_name ); + return false; + } + + $instance = new static( $data['refers'], $data['value'] ); + if ( ! $instance->validate() ) { + delete_option( self::$primary_option_name ); + return false; + } + + return $instance; + } +} diff --git a/src/SiteClassification/SecondaryType.php b/src/SiteClassification/SecondaryType.php new file mode 100644 index 0000000..7ddbb7f --- /dev/null +++ b/src/SiteClassification/SecondaryType.php @@ -0,0 +1,79 @@ +refers ) { + return true; + } + + // Retrieve the selected primary type. + $primary = PrimaryType::instantiate_from_option(); + // If it does not exist, then give benefit of doubt. + if ( ! ( $primary instanceof PrimaryType ) ) { + return true; + } + + $classification = SiteClassification::get(); + $secondary_types = $classification['types'][ $primary->value ]['secondaryTypes']; + // If secondaryTypes does not exist or the selected slug does not exist then return false. + if ( ! isset( $secondary_types ) || ! isset( $secondary_types[ $this->value ] ) ) { + return false; + } + + return true; + } + + /** + * Instantiates a class object from the data stored in the option. + * + * @return SecondaryType|boolean + */ + public static function instantiate_from_option() { + $data = get_option( self::$secondary_option_name, false ); + + if ( ! $data || ! is_array( $data ) || ! isset( $data['refers'] ) || ! isset( $data['value'] ) ) { + delete_option( self::$secondary_option_name ); + return false; + } + + $instance = new static( $data['refers'], $data['value'] ); + if ( ! $instance->validate() ) { + delete_option( self::$secondary_option_name ); + return false; + } + + return $instance; + } +} diff --git a/src/SiteClassification/SiteClassification.php b/src/SiteClassification/SiteClassification.php new file mode 100644 index 0000000..2ffe094 --- /dev/null +++ b/src/SiteClassification/SiteClassification.php @@ -0,0 +1,103 @@ +request( + 'GET', + array( + 'headers' => array( + 'Accept' => 'application/json', + ), + ) + ); + + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + return array(); + } + + $body = wp_remote_retrieve_body( $response ); + $data = json_decode( $body, true ); + if ( ! $data || ! is_array( $data ) ) { + return array(); + } + + return $data; + } + + /** + * Fetch site classification data from a static JSON file. + * + * @return array + */ + public static function fetch_from_static_file() { + $filename = realpath( __DIR__ . '/../Data/Static/site-classification.json' ); + + if ( ! file_exists( $filename ) ) { + return array(); + } + + $data = json_decode( file_get_contents( $filename ), true ); + if ( ! $data ) { + return array(); + } + + return $data; + + } +} diff --git a/src/SiteClassification/Types.php b/src/SiteClassification/Types.php new file mode 100644 index 0000000..269a3c2 --- /dev/null +++ b/src/SiteClassification/Types.php @@ -0,0 +1,96 @@ +option_name = $option_name; + $this->refers = $refers; + $this->value = $value; + } + + /** + * Sets the refers property. + * + * @param string $refers Indicates what the value refers to, slug(from default slugs)|custom(from a custom input field). + * @return void + */ + public function set_refers( $refers ) { + $this->refers = $refers; + } + + /** + * Sets the value property. + * + * @param string $value The actual value of the site classification type. + * @return void + */ + public function set_value( $value ) { + $this->value = $value; + } + + /** + * Saves data to the option after validation. + * + * @return boolean + */ + public function save() { + if ( ! $this->validate() ) { + return false; + } + update_option( $this->option_name, $this->to_array() ); + return true; + + } + + /** + * Converts the object to an array. + * + * @return array + */ + public function to_array() { + return array( + 'refers' => $this->refers, + 'value' => $this->value, + ); + } + + /** + * Validates the site classification type data. + * + * @return boolean + */ + abstract public function validate(); + +}