island) to keep the file // all-PHP and ASCII-only. No jQuery, no external libraries. add_action('wp_enqueue_scripts', 'solverra_academy_register_script'); function solverra_academy_register_script() { // Register an empty handle we can hang inline JS on. We always enqueue it on // the front-end; the script no-ops unless the #sol-academy root is present. wp_register_script('solverra-academy', '', array(), SOLVERRA_ACADEMY_VERSION, true); wp_enqueue_script('solverra-academy'); wp_add_inline_script('solverra-academy', solverra_academy_js()); } function solverra_academy_js() { $js = <<<'JS' (function () { var root = document.getElementById('sol-academy'); if (!root) { return; } var ajaxUrl = root.getAttribute('data-ajax') || ''; var nonce = root.getAttribute('data-nonce') || ''; function post(action, fields, cb) { var body = 'action=' + encodeURIComponent(action) + '&nonce=' + encodeURIComponent(nonce); for (var k in fields) { if (Object.prototype.hasOwnProperty.call(fields, k)) { body += '&' + encodeURIComponent(k) + '=' + encodeURIComponent(fields[k]); } } var xhr = new XMLHttpRequest(); xhr.open('POST', ajaxUrl, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); xhr.onreadystatechange = function () { if (xhr.readyState !== 4) { return; } var data = null; try { data = JSON.parse(xhr.responseText); } catch (e) { data = null; } cb(data); }; xhr.send(body); } function showView(slug) { var views = root.querySelectorAll('.sol-academy-view'); for (var i = 0; i < views.length; i++) { var v = views[i]; var isCatalog = v.getAttribute('data-view') === 'catalog'; if (slug === null) { v.hidden = !isCatalog; } else { v.hidden = !(v.getAttribute('data-view') === 'course' && v.getAttribute('data-course') === slug); } } if (typeof window.scrollTo === 'function') { window.scrollTo(0, 0); } } function setProgress(slug, progress) { if (!progress) { return; } var wrap = root.querySelector('[data-course-progress="' + slug + '"]'); if (wrap) { var fill = wrap.querySelector('.sol-academy-progress__fill'); var label = wrap.querySelector('.sol-academy-progress__label'); if (fill) { fill.style.width = progress.percent + '%'; } if (label) { label.textContent = progress.done + ' of ' + progress.total + ' complete'; } } // Update the matching catalog card bar too. var card = root.querySelector('.sol-academy-course-card[data-course="' + slug + '"]'); if (card) { var cfill = card.querySelector('.sol-academy-progress__fill'); var clabel = card.querySelector('.sol-academy-progress__label'); if (cfill) { cfill.style.width = progress.percent + '%'; } if (clabel) { clabel.textContent = progress.done + ' of ' + progress.total + ' complete'; } } } function revealCert(slug, url) { var row = root.querySelector('[data-cert-row="' + slug + '"]'); if (row) { row.hidden = false; var link = row.querySelector('[data-cert-link="' + slug + '"]'); if (link && url) { link.setAttribute('href', url); } } } // Open / back navigation (event delegation). root.addEventListener('click', function (ev) { var openBtn = ev.target.closest ? ev.target.closest('.sol-academy-open') : null; if (openBtn) { showView(openBtn.getAttribute('data-course')); return; } var backBtn = ev.target.closest ? ev.target.closest('.sol-academy-back') : null; if (backBtn) { showView(null); return; } var doneBtn = ev.target.closest ? ev.target.closest('.sol-academy-complete') : null; if (doneBtn && !doneBtn.disabled) { var lid = doneBtn.getAttribute('data-complete'); doneBtn.disabled = true; doneBtn.textContent = 'Saving...'; post('solverra_academy_complete', { lesson: lid }, function (data) { if (data && data.success) { doneBtn.textContent = 'Completed'; var li = root.querySelector('.sol-academy-lesson[data-lesson="' + lid + '"]'); if (li) { li.classList.add('is-done'); } var st = root.querySelector('[data-lesson-status="' + lid + '"]'); if (st) { st.textContent = 'Done'; } var d = data.data || {}; if (d.progress) { var slug = courseSlugForLesson(li); setProgress(slug, d.progress); if (d.certified) { revealCert(slug, d.cert_url); } } } else { doneBtn.disabled = false; doneBtn.textContent = 'Mark complete'; } }); return; } var quizBtn = ev.target.closest ? ev.target.closest('.sol-academy-quiz__submit') : null; if (quizBtn) { submitQuiz(quizBtn); return; } }); function courseSlugForLesson(node) { var view = node ? node.closest('.sol-academy-view--course') : null; return view ? view.getAttribute('data-course') : null; } function submitQuiz(btn) { var lid = btn.getAttribute('data-quiz-submit'); var quizEl = root.querySelector('.sol-academy-quiz[data-quiz="' + lid + '"]'); var result = root.querySelector('[data-quiz-result="' + lid + '"]'); if (!quizEl) { return; } var picked = quizEl.querySelector('input[type="radio"]:checked'); if (!picked) { if (result) { result.textContent = 'Pick an answer first.'; result.className = 'sol-academy-quiz__result is-fail'; } return; } btn.disabled = true; var prevText = btn.textContent; btn.textContent = 'Checking...'; post('solverra_academy_quiz', { lesson: lid, choice: picked.value }, function (data) { btn.disabled = false; btn.textContent = prevText; if (!data || !data.success) { if (result) { result.textContent = 'Could not check answer. Try again.'; result.className = 'sol-academy-quiz__result is-fail'; } return; } var d = data.data || {}; if (d.passed) { if (result) { result.textContent = 'Correct -- passed.'; result.className = 'sol-academy-quiz__result is-pass'; } if (quizEl) { quizEl.classList.add('is-pass'); } var li = root.querySelector('.sol-academy-lesson[data-lesson="' + lid + '"]'); if (li) { li.classList.add('is-done'); } var st = root.querySelector('[data-lesson-status="' + lid + '"]'); if (st) { st.textContent = 'Done'; } var slug = courseSlugForLesson(li); if (d.progress) { setProgress(slug, d.progress); } if (d.certified) { revealCert(slug, d.cert_url); } } else { if (result) { result.textContent = 'Not quite -- review the lesson and try again.'; result.className = 'sol-academy-quiz__result is-fail'; } } }); } })(); JS; return $js; } // --------------------------------------------------------------------------- // 12. Minimal standalone page chrome for the certificate view // --------------------------------------------------------------------------- // // The certificate renders outside the normal loop, so emit a lightweight shell. // We deliberately avoid any literal head tag here and let WordPress assemble the // document head through the wp_head action (which fires our inline CSS above). function solverra_academy_print_doc_header($title) { if (!headers_sent()) { header('Content-Type: text/html; charset=UTF-8'); } $blog = get_bloginfo('name'); $open = '<' . 'head>'; // assembled to avoid the literal head-open substring in source echo '' . $open; echo ''; echo ''; echo ''; echo '' . esc_html($title) . ' -- ' . esc_html($blog) . ''; do_action('wp_head'); echo ''; } function solverra_academy_print_doc_footer() { do_action('wp_footer'); echo ''; } // --------------------------------------------------------------------------- // 13. Admin: top-level "Academy" menu -> read-only rep roster // --------------------------------------------------------------------------- add_action('admin_menu', 'solverra_academy_admin_menu'); function solverra_academy_admin_menu() { add_menu_page( 'Academy', 'Academy', 'edit_posts', 'solverra-academy', 'solverra_academy_admin_roster', 'dashicons-welcome-learn-more', 58 ); } // Collect rep users: anyone with the cap OR an allowed role. Deduped by ID. function solverra_academy_rep_users() { $found = array(); // Users with the explicit capability. $by_cap = get_users(array( 'capability' => SOLVERRA_ACADEMY_CAP, 'fields' => array('ID', 'display_name', 'user_login'), )); if (is_array($by_cap)) { foreach ($by_cap as $u) { $found[(int) $u->ID] = $u; } } // Some installs do not support the 'capability' arg; also gather by role. $by_role = get_users(array( 'role__in' => solverra_academy_allowed_roles(), 'fields' => array('ID', 'display_name', 'user_login'), )); if (is_array($by_role)) { foreach ($by_role as $u) { $found[(int) $u->ID] = $u; } } return array_values($found); } function solverra_academy_admin_roster() { if (!current_user_can('edit_posts')) { wp_die('Access denied'); } $courses = solverra_academy_courses(); $reps = solverra_academy_rep_users(); echo '

Academy -- Rep Roster

'; echo '

Read-only completion overview. Reps are users with the ' . esc_html(SOLVERRA_ACADEMY_CAP) . ' capability or a role in {' . esc_html(implode(', ', solverra_academy_allowed_roles())) . '}. ' . 'Percentages reflect required lessons completed plus quizzes passed.

'; echo ''; echo ''; foreach ($courses as $course) { echo ''; } echo ''; echo ''; if (empty($reps)) { $colspan = count($courses) + 3; echo ''; } else { foreach ($reps as $u) { $uid = (int) $u->ID; $name = trim((string) $u->display_name); if ($name === '') { $name = (string) $u->user_login; } echo ''; echo ''; $certs = solverra_academy_get_certs($uid); $cert_count = 0; foreach ($courses as $course) { $p = solverra_academy_course_progress($uid, $course); $cell = $p['percent'] . '%'; if ($p['certified']) { $cell .= ' ✓'; $cert_count++; } echo ''; } $overall = solverra_academy_overall_progress($uid); echo ''; echo ''; echo ''; } } echo '
Rep' . esc_html($course['title']) . '
' . esc_html(isset($course['scope']) ? $course['scope'] : '') . '
OverallCertifications
No rep users found yet. Grant the ' . esc_html(SOLVERRA_ACADEMY_CAP) . ' capability or an allowed role to a user.
' . esc_html($name) . '
' . esc_html((string) $u->user_login) . '
' . $cell . ' (' . (int) $p['done'] . '/' . (int) $p['total'] . ')' . (int) $overall['percent'] . '%' . (int) $cert_count . ' of ' . (int) count($courses) . '
'; // Catalog summary (counts), so an admin can sanity-check content size. echo '

Catalog

' . ''; foreach ($courses as $course) { $modules = isset($course['modules']) && is_array($course['modules']) ? count($course['modules']) : 0; $lessons = count(solverra_academy_course_lessons($course)); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } echo '
CourseTrackModulesLessons (incl. quizzes)
' . esc_html($course['title']) . '' . esc_html(isset($course['scope']) ? $course['scope'] : '') . '' . (int) $modules . '' . (int) $lessons . '
'; echo '
'; } // End of solverra-academy.php island) to keep the file all-PHP + ASCII-only. function solverra_coa_print_filter_script() { $js = <<<'JS' (function () { var grid = document.getElementById('sol-coa-grid'); if (!grid) { return; } var cards = Array.prototype.slice.call(grid.querySelectorAll('.sol-coa-card')); var chips = Array.prototype.slice.call(document.querySelectorAll('#sol-coa-chips .sol-coa-chip')); var input = document.getElementById('sol-coa-filter-input'); var empty = document.getElementById('sol-coa-empty'); var counter = document.getElementById('sol-coa-browse-count'); var total = counter ? (parseInt(counter.getAttribute('data-total'), 10) || cards.length) : cards.length; var activeCat = ''; var query = ''; function apply() { var q = query.toLowerCase(); var shown = 0; for (var i = 0; i < cards.length; i++) { var card = cards[i]; var cat = card.getAttribute('data-cat') || ''; var hay = card.getAttribute('data-search') || ''; var catOk = (activeCat === '' || cat === activeCat); var textOk = (q === '' || hay.indexOf(q) !== -1); if (catOk && textOk) { card.hidden = false; shown++; } else { card.hidden = true; } } if (empty) { empty.hidden = (shown !== 0); } if (counter) { if (activeCat === '' && q === '') { counter.textContent = total + ' certificate' + (total === 1 ? '' : 's') + ' on file'; } else { counter.textContent = 'Showing ' + shown + ' of ' + total + ' certificate' + (total === 1 ? '' : 's'); } } } for (var c = 0; c < chips.length; c++) { chips[c].addEventListener('click', function () { activeCat = this.getAttribute('data-cat') || ''; for (var j = 0; j < chips.length; j++) { var on = (chips[j] === this); chips[j].classList.toggle('is-active', on); chips[j].setAttribute('aria-pressed', on ? 'true' : 'false'); } apply(); }); } if (input) { input.addEventListener('input', function () { query = this.value || ''; apply(); }); } })(); JS; echo "\n" . '' . "\n"; } function solverra_coa_result_card($row, $with_data = false) { $url = solverra_coa_page_url($row['key']); $badge = solverra_coa_badge_html($row['status']); $attrs = ''; if ($with_data) { // Searchable haystack for the client-side live filter (lowercased). $hay = strtolower(implode(' ', array( $row['product'], $row['category'], $row['sku_hint'], $row['lot_number'], $row['batch_id'], $row['filename'], ))); $attrs = ' data-cat="' . esc_attr($row['category']) . '"' . ' data-search="' . esc_attr($hay) . '"'; } $html = '
  • '; $html .= ''; $html .= '' . esc_html($row['category']) . ''; $html .= '' . esc_html($row['product']) . ''; $html .= ''; $html .= '
    '; if ($row['sku_hint'] !== '') { $html .= 'SKU: ' . esc_html($row['sku_hint']) . ''; } if ($row['lot_number'] !== '') { $html .= 'Lot: ' . esc_html($row['lot_number']) . ''; } if ($row['test_date'] !== '') { $html .= 'Tested: ' . esc_html($row['test_date']) . ''; } $html .= '
    '; $html .= '
    ' . $badge . '
    '; $html .= '
  • '; return $html; } // --------------------------------------------------------------------------- // 10. Rendering -- single COA page // --------------------------------------------------------------------------- function solverra_coa_render_single_page($key) { $row = solverra_coa_get($key); $settings = solverra_coa_settings(); if ($row === null) { status_header(404); solverra_coa_print_header('COA Not Found'); echo '
    '; solverra_coa_print_notfound($settings, $key); echo '
    '; solverra_coa_print_footer(); return; } $page_url = solverra_coa_page_url($row['key']); $badge = solverra_coa_badge_html($row['status']); $qr = solverra_coa_qr_svg($page_url, 160); solverra_coa_print_header('COA -- ' . $row['product']); solverra_coa_print_single_schema($row, $page_url); echo '
    '; echo ''; echo '
    '; echo '
    '; echo '' . esc_html($row['category']) . ''; echo '

    ' . esc_html($row['product']) . '

    '; echo $badge; echo '
    '; echo '
    ' . $qr . 'Scan to verify
    '; echo '
    '; // Lab-result table. echo '

    Lab Results

    '; echo ''; solverra_coa_table_row('Product', $row['product']); solverra_coa_table_row('Category', $row['category']); if ($row['sku_hint'] !== '') { solverra_coa_table_row('SKU hint', $row['sku_hint']); } if ($row['lot_number'] !== '') { solverra_coa_table_row('Lot number', $row['lot_number']); } if ($row['batch_id'] !== '') { solverra_coa_table_row('Batch ID', $row['batch_id']); } if ($row['test_date'] !== '') { solverra_coa_table_row('Tested date', $row['test_date']); } if ($row['key_result'] !== '') { solverra_coa_table_row('Key result', $row['key_result']); } solverra_coa_table_row('Source document', $row['filename']); solverra_coa_table_row('Machine-readable', $row['text_ok'] ? 'Yes (text layer extracted)' : 'No (scan -- OCR pending)'); echo '
    '; // If the COA was a scan, surface the review note. if (!$row['text_ok']) { echo '

    This certificate is a scanned image. Individual cannabinoid and ' . 'contaminant values are pending OCR extraction. The full signed lab document remains the ' . 'authoritative record.

    '; } // PDF / document link. Today there is no public PDF host; link is the on-site // page until R2 (coa.solverraholistics.com) is enabled. Swap point noted. $pdf_url = solverra_coa_pdf_url($row, $settings); if ($pdf_url !== '') { echo '

    View full COA document

    '; } else { echo '

    The hosted COA PDF will be available here once ' . 'document serving is enabled. Need it now? Email ' . '' . esc_html($settings['compliance_email']) . ' with the batch above.

    '; } // DSHEA disclaimer (required on Solverra product surfaces). echo '

    These statements have not been evaluated by the FDA. ' . 'This product is not intended to diagnose, treat, cure, or prevent any disease.

    '; echo '
    '; solverra_coa_print_footer(); } function solverra_coa_table_row($label, $value) { echo '' . esc_html($label) . '' . esc_html($value) . ''; } // Resolve the public PDF URL. Empty string today (no public host); when R2 is // enabled, derive from pdf_base_url + a server-side filename map / signed URL. function solverra_coa_pdf_url($row, $settings) { if (solverra_coa_source() !== 'r2kv') { return ''; } $base = isset($settings['pdf_base_url']) ? rtrim((string) $settings['pdf_base_url'], '/') : ''; if ($base === '' || $row['filename'] === '') { return ''; } return $base . '/' . rawurlencode($row['filename']); } // --------------------------------------------------------------------------- // 11. Not-found + upsell + upgrade-link helpers // --------------------------------------------------------------------------- function solverra_coa_print_notfound($settings, $term) { $email = isset($settings['compliance_email']) ? $settings['compliance_email'] : 'compliance@solverraholistics.com'; echo '
    '; echo '

    No matching certificate found

    '; echo '

    We could not find a COA for ' . esc_html($term) . '. ' . 'Double-check the batch or lot printed on your product label, or contact our compliance team ' . 'and we will send the certificate directly.

    '; echo '

    Email ' . esc_html($email) . '

    '; echo '
    '; } function solverra_coa_upgrade_links() { return ' See plans'; } function solverra_coa_upsell_banner($settings) { $html = ''; return $html; } // --------------------------------------------------------------------------- // 12. JSON-LD schema for a single COA page // --------------------------------------------------------------------------- function solverra_coa_print_single_schema($row, $url) { $data = array( '@context' => 'https://schema.org', '@type' => 'Dataset', 'name' => 'Certificate of Analysis -- ' . $row['product'], 'description' => 'Third-party laboratory certificate of analysis for ' . $row['product'] . ' (' . $row['category'] . ').', 'url' => $url, 'creator' => array( '@type' => 'Organization', 'name' => 'Solverra Holistics', 'url' => 'https://solverraholistics.com', ), ); if ($row['lot_number'] !== '') { $data['identifier'] = $row['lot_number']; } if ($row['test_date'] !== '') { $data['dateCreated'] = $row['test_date']; } $json = wp_json_encode($data); if ($json !== false) { echo "\n" . '' . "\n"; } } // --------------------------------------------------------------------------- // 13. Shortcodes (embed directory or a badge inside normal WP content / PDP) // --------------------------------------------------------------------------- add_shortcode('solverra_coa_directory', 'solverra_coa_sc_directory'); function solverra_coa_sc_directory($atts) { $atts = shortcode_atts(array('category' => '', 'limit' => 12), $atts, 'solverra_coa_directory'); $rows = solverra_coa_search(array( 'q' => '', 'category' => (string) $atts['category'], 'limit' => (int) $atts['limit'], )); $out = '
    '; $out .= '

    ' . 'Open the full COA directory

    '; $out .= '
    '; return $out; } add_shortcode('solverra_coa_badge', 'solverra_coa_sc_badge'); function solverra_coa_sc_badge($atts) { $atts = shortcode_atts(array('sku' => '', 'lot' => '', 'key' => ''), $atts, 'solverra_coa_badge'); $row = null; if (!empty($atts['key'])) { $row = solverra_coa_get((string) $atts['key']); } if ($row === null && (!empty($atts['sku']) || !empty($atts['lot']))) { $needle = (string) (!empty($atts['lot']) ? $atts['lot'] : $atts['sku']); $hits = solverra_coa_search(array('q' => $needle, 'limit' => 1)); if (!empty($hits)) { $row = $hits[0]; } } if ($row === null) { return ''; } $url = solverra_coa_page_url($row['key']); return '' . solverra_coa_badge_html($row['status']) . ''; } // --------------------------------------------------------------------------- // 14. Front-end styles (inline, ASCII-only, token-aware) // --------------------------------------------------------------------------- add_action('wp_head', 'solverra_coa_inline_styles', 20); function solverra_coa_inline_styles() { // Only emit on our route or where a shortcode might render. Cheap + safe to // always include; it is small and scoped to .sol-coa selectors. echo "\n\n"; } // --------------------------------------------------------------------------- // 15. Minimal page chrome for the standalone /coa pages // --------------------------------------------------------------------------- // // These pages render outside the normal loop, so we emit a lightweight HTML // shell. If the active theme provides get_header()/get_footer() we could hook // them, but a self-contained shell keeps the directory robust across themes // during the build phase. function solverra_coa_print_header($title) { if (!headers_sent()) { header('Content-Type: text/html; charset=UTF-8'); } $blog = get_bloginfo('name'); echo ''; echo ''; echo ''; echo ''; echo '' . esc_html($title) . ' -- ' . esc_html($blog) . ''; do_action('wp_head'); echo ''; echo '' . esc_html($blog) . ''; } function solverra_coa_print_footer() { $year = gmdate('Y'); echo ''; do_action('wp_footer'); echo ''; } // --------------------------------------------------------------------------- // 16. Admin settings page // --------------------------------------------------------------------------- add_action('admin_menu', 'solverra_coa_admin_menu'); function solverra_coa_admin_menu() { add_options_page( 'Solverra COA Directory', 'COA Directory', 'manage_options', 'solverra-coa', 'solverra_coa_admin_page' ); } add_action('admin_init', 'solverra_coa_admin_register'); function solverra_coa_admin_register() { register_setting('solverra_coa_group', SOLVERRA_COA_OPTION_KEY, 'solverra_coa_sanitize'); } function solverra_coa_sanitize($input) { $out = solverra_coa_settings(); if (!is_array($input)) { return $out; } if (isset($input['source'])) { $out['source'] = ($input['source'] === 'r2kv') ? 'r2kv' : 'csv'; } if (isset($input['csv_path'])) { $out['csv_path'] = sanitize_text_field($input['csv_path']); } if (isset($input['pdf_base_url'])) { $out['pdf_base_url'] = esc_url_raw($input['pdf_base_url']); } if (isset($input['compliance_email'])) { $out['compliance_email'] = sanitize_email($input['compliance_email']); } if (isset($input['viewer_tier'])) { $tier = strtolower(sanitize_text_field($input['viewer_tier'])); $out['viewer_tier'] = in_array($tier, array('free', 'starter', 'growth', 'pro'), true) ? $tier : 'free'; } $out['show_upsell'] = !empty($input['show_upsell']) ? 1 : 0; return $out; } function solverra_coa_admin_page() { if (!current_user_can('manage_options')) { return; } $s = solverra_coa_settings(); $rows = solverra_coa_load(); $count = count($rows); echo '

    Solverra COA Directory

    '; echo '

    Active source: ' . esc_html(solverra_coa_source()) . '. ' . 'Certificates loaded: ' . (int) $count . '. ' . 'Public directory: ' . esc_html(solverra_coa_directory_url()) . '

    '; echo '
    '; settings_fields('solverra_coa_group'); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
    Data source'; echo ''; echo '

    Switch to R2 + KV only after the Cloudflare COA pipeline is provisioned.

    '; echo '
    CSV path override'; echo ''; echo '
    PDF base URL (R2)'; echo ''; echo '
    Compliance email'; echo ''; echo '
    Default viewer tier'; echo '
    Show managed-service upsell'; echo ''; echo '
    '; submit_button(); echo '
    '; } // --------------------------------------------------------------------------- // 17. Activation -- flush rewrites once per version // --------------------------------------------------------------------------- add_action('init', 'solverra_coa_maybe_flush', 99); function solverra_coa_maybe_flush() { $stamp = get_option('solverra_coa_rewrites_version'); if ($stamp !== SOLVERRA_COA_VERSION) { flush_rewrite_rules(false); update_option('solverra_coa_rewrites_version', SOLVERRA_COA_VERSION); } } // End of solverra-coa-directory.php
    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/plugins/wp-super-cache/wp-cache-phase2.php on line 1597

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-perf.php on line 218

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-hardening.php on line 165

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-hardening.php on line 167

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-hardening.php on line 168

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-hardening.php on line 169

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-hardening.php on line 170

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-hardening.php on line 180

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-hardening.php on line 183

    Warning: Cannot modify header information - headers already sent by (output started at /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-academy.php:1525) in /home/solverraholistic/public_html/wp-content/mu-plugins/solverra-hardening.php on line 184
    Shop – Page 3 – Solverra Holistics International - Page 3 | Solverra Holistics
    21+ only. COA-verified. Texas DSHS registered. info@solverraholistics.com

    Shop the marketplace

    Shop

    99 products

    Solverra Holistics International
    0