366 lines
No EOL
12 KiB
PHP
366 lines
No EOL
12 KiB
PHP
<?php
|
|
|
|
class AR_Model_Viewer_Renderer
|
|
{
|
|
/**
|
|
* @var AR_Model_Viewer_Settings_Page
|
|
*/
|
|
private $settings = array('ar_variants' => [], 'modal' => false);
|
|
public $isPremiumPlan;
|
|
private $defaultSettings = array('modal' => false);
|
|
private $defaultAttributes = array('src' => '', 'ios-src' => '', 'poster' => '', 'disable-zoom' => false, 'auto-rotate' => false, 'skybox-image' => '', 'ar-placement' => 'floor', 'ar-scale' => 'auto', 'autoplay' => false);
|
|
private $modelAttributes = array();
|
|
private $defaultStyles = array('margin' => '0 auto');
|
|
private $premiumHandler;
|
|
private $settingsOptions;
|
|
|
|
|
|
public function __construct()
|
|
{
|
|
$this->settingsOptions = AR_Model_Viewer_Settings_Page::getOptions();
|
|
$this->isPremiumPlan = AR_Model_Viewer_Settings_Page::is_premium_plan();
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']);
|
|
add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']);
|
|
require_once(__DIR__ . '/ar-model-premium.php');
|
|
$this->premiumHandler = new AR_Model_Viewer_Premium();
|
|
add_shortcode('ar_model_viewer', [$this, 'render_shortcode']);
|
|
}
|
|
|
|
public function render_shortcode($atts)
|
|
{
|
|
$atts = shortcode_atts($this->defaultAttributes, $atts);
|
|
$this->modelAttributes = $atts;
|
|
return $this->render_ar();
|
|
}
|
|
|
|
public function enqueue_scripts()
|
|
{
|
|
|
|
add_filter('script_loader_tag', [$this, 'add_type_to_script'], 1, 3);
|
|
wp_register_script('model-viewer', plugins_url('../../js/libs/model-viewer.min.js', __FILE__, [], '3.0.0'));
|
|
wp_enqueue_script('model-viewer');
|
|
|
|
remove_filter('script_loader_tag', [$this, 'add_type_to_script']);
|
|
|
|
wp_register_script('model-viewer-renderer', plugins_url('../../js/ar-model-viewer-renderer.js', __FILE__), array('jquery'), WP_DEBUG ? time() : AR_Model_Viewer::VERSION);
|
|
wp_enqueue_script('model-viewer-renderer');
|
|
|
|
wp_enqueue_style('AR Model Configurator', plugins_url('../../css/ar-model-viewer-public.css', __FILE__), [], WP_DEBUG ? time() : AR_Model_Viewer::VERSION);
|
|
}
|
|
|
|
public function localize($extra = [])
|
|
{
|
|
|
|
global $post;
|
|
if (!$post) {
|
|
return;
|
|
}
|
|
$settings = $this->get_post_settings($post->ID);
|
|
$att_poster_src = $settings['poster'];
|
|
$att_bg_src = $settings['skybox-image'];
|
|
$att_src = $settings['src'];
|
|
$att_ios_src = $settings['ios-src'];
|
|
$ar_auto_rotate = $settings['auto-rotate'];
|
|
$ar_model_scaling = $settings['ar-scale'];
|
|
$ar_model_placement = $settings['ar-placement'];
|
|
if (empty($att_poster_src) && function_exists('wc_placeholder_img_src')) {
|
|
$att_poster_src = wc_placeholder_img_src();
|
|
}
|
|
$jsArr = array(
|
|
"arSrc" => ["url" => $att_src, "name" => "ar_model_viewer_file"],
|
|
"arIosSrc" => ["url" => $att_ios_src, "name" => "ar_model_viewer_file_ios"],
|
|
"arBgImage" => ["url" => $att_bg_src, "name" => "ar_model_viewer_skybox_image"],
|
|
"arPosterImage" => ["url" => $att_poster_src, "name" => "ar_model_viewer_poster_image"],
|
|
"autoRotate" => ["value" => $ar_auto_rotate, "name" => "ar_model_rotate"],
|
|
"arPlacement" => ["value" => $ar_model_placement, "name" => "ar_placement_model"],
|
|
"arModelScaling" => ["value" => $ar_model_scaling, "name" => "ar_model_scaling_lock"],
|
|
);
|
|
if ($this->isPremiumPlan) {
|
|
$jsArr = $this->premiumHandler->localize_extras($jsArr, $settings);
|
|
}
|
|
|
|
wp_localize_script('ar-model-viewer', 'arModelViewerSettings', array_merge($jsArr, $extra));
|
|
}
|
|
|
|
public function add_type_to_script($tag, $handle, $src)
|
|
{
|
|
if ($handle == 'model-viewer') {
|
|
$tag = '<script type="module" src="' . esc_url($src) . '"></script>';
|
|
}
|
|
return $tag;
|
|
}
|
|
|
|
public function get_attribute($name)
|
|
{
|
|
return isset($this->modelAttributes[$name]) ? $this->modelAttributes[$name] : null;
|
|
}
|
|
|
|
public function get_post_settings($post_id)
|
|
{
|
|
$settings = get_post_meta($post_id, 'ar_model_viewer_settings', true);
|
|
if (!is_array($settings)) {
|
|
$defaults = $this->get_default_attributes();
|
|
$settings = array_merge($defaults, ['ar_variants' => [], 'wc_variants' => []]);
|
|
}
|
|
if (!isset($settings['ar_variants'])) {
|
|
$settings['ar_variants'] = [];
|
|
}
|
|
if (!isset($settings['wc_variants'])) {
|
|
$settings['wc_variants'] = [];
|
|
}
|
|
if ($this->isPremiumPlan) {
|
|
$settings = $this->premiumHandler->get_post_premium_settings($settings);
|
|
}
|
|
|
|
$update_settings_arr = array(array("src","src-id"), array("ios-src","ios-src-id"), array("skybox-image","skybox-image-src-id"), array("poster","poster-src-id"));
|
|
foreach($update_settings_arr as $value){
|
|
$this->backward_compatible_keys($settings, $value[0], $value[1]);
|
|
}
|
|
|
|
return $settings;
|
|
}
|
|
|
|
private function backward_compatible_keys(&$settings, $src_key, $id_key)
|
|
{
|
|
if (empty($settings[$src_key]) && isset($settings[$id_key])) {
|
|
$id = $settings[$id_key];
|
|
if(!empty($id)){
|
|
$settings[$src_key] = wp_get_attachment_url($id);
|
|
};
|
|
if (empty($settings[$src_key])) {
|
|
$settings[$src_key] = '';
|
|
};
|
|
unset($settings[$id_key]);
|
|
}
|
|
}
|
|
|
|
|
|
public function get_default_attributes()
|
|
{
|
|
return $this->defaultAttributes;
|
|
}
|
|
|
|
public function set_attributes($values)
|
|
{
|
|
$this->setAutoPlayAnimation();
|
|
if (empty($this->modelAttributes)) {
|
|
$this->modelAttributes = $this->defaultAttributes;
|
|
}
|
|
$newArr = wp_parse_args($values, $this->modelAttributes);
|
|
$this->modelAttributes = $newArr;
|
|
}
|
|
|
|
public function set_from_product($product_id)
|
|
{
|
|
|
|
$current_settings = $this->get_post_settings($product_id);
|
|
|
|
$attributes = array_keys($this->get_default_attributes());
|
|
|
|
$filteredArray = array_filter($current_settings, function ($key) use ($attributes) {
|
|
return in_array($key, $attributes);
|
|
}, ARRAY_FILTER_USE_KEY);
|
|
|
|
$this->set_attributes($filteredArray);
|
|
$this->settings = array_merge($this->settings, $current_settings);
|
|
return $this;
|
|
}
|
|
|
|
public function save_post_settings($post_id)
|
|
{
|
|
|
|
$current_settings = $this->get_post_settings($post_id);
|
|
|
|
if (!is_array($current_settings)) {
|
|
$current_settings = $this->get_default_attributes();
|
|
}
|
|
if (isset($_POST['ar_model_viewer_file'])) {
|
|
$current_settings['src'] = $_POST['ar_model_viewer_file'];
|
|
}
|
|
if (isset($_POST['ar_model_viewer_file_ios'])) {
|
|
$current_settings['ios-src'] = $_POST['ar_model_viewer_file_ios'];
|
|
}
|
|
|
|
if (isset($_POST['ar_model_viewer_poster_image'])) {
|
|
$current_settings['poster'] = $_POST['ar_model_viewer_poster_image'];
|
|
}
|
|
|
|
if (isset($_POST['ar_model_viewer_skybox_image'])) {
|
|
$current_settings['skybox-image'] = $_POST['ar_model_viewer_skybox_image'];
|
|
}
|
|
|
|
if (isset($_POST['ar_model_rotate'])) {
|
|
$current_settings['auto-rotate'] = 'true';
|
|
} else {
|
|
$current_settings['auto-rotate'] = 'false';
|
|
}
|
|
|
|
if (isset($_POST['ar_placement_model'])) {
|
|
$current_settings['ar-placement'] = $_POST['ar_placement_model'];
|
|
}
|
|
if (isset($_POST['ar_model_scaling_lock'])) {
|
|
$current_settings['ar-scale'] = 'fixed';
|
|
} else {
|
|
$current_settings['ar-scale'] = 'auto';
|
|
}
|
|
if ($this->isPremiumPlan) {
|
|
$current_settings = $this->premiumHandler->save_post_premium_settings($post_id, $current_settings);
|
|
}
|
|
|
|
update_post_meta($post_id, 'ar_model_viewer_settings', $current_settings);
|
|
}
|
|
|
|
public function save_variation_settings($variation_id, $i)
|
|
{
|
|
if ($this->isPremiumPlan) {
|
|
$product_id = wp_get_post_parent_id($variation_id);
|
|
$current_settings = $this->get_post_settings($product_id);
|
|
$current_settings = $this->premiumHandler->save_variation_premium_settings($variation_id, $i, $current_settings);
|
|
update_post_meta($product_id, 'ar_model_viewer_settings', $current_settings);
|
|
}
|
|
}
|
|
|
|
public function set_styles($values)
|
|
{
|
|
$newArr = wp_parse_args($values, $this->defaultStyles);
|
|
$this->defaultStyles = $newArr;
|
|
}
|
|
|
|
public function set_settings($values)
|
|
{
|
|
$newArr = wp_parse_args($values, $this->settings);
|
|
$this->settings = $newArr;
|
|
}
|
|
|
|
|
|
public function render_ar()
|
|
{
|
|
$desktopModalOn = $this->showDesktopModalBtn();
|
|
$desktopModalDescription = $this->getDesktopModalText();
|
|
$view_in_ar_desktop_modal = $this->append_modal('<div style="white-space: pre-wrap">'.$desktopModalDescription.'</div>', 'desktop-ar-modal');
|
|
$ar_attributes = $this->get_attributes_string();
|
|
$ar_styles = $this->get_styles_string();
|
|
$html = '<div class="ar-model-contents">
|
|
<model-viewer-preview>
|
|
<model-viewer
|
|
loading="eager"
|
|
class="model-viewer"
|
|
style="max-width: 100%; max-height: 100%; --poster-color:transparent; min-width:350px; min-height:350px ' . $ar_styles . '"
|
|
bounds="tight"
|
|
ar
|
|
ar-modes="webxr scene-viewer quick-look"
|
|
camera-controls
|
|
environment-image="neutral"
|
|
shadow-intensity="1"
|
|
'.$ar_attributes.'
|
|
>
|
|
'.$this->get_desktop_ar_modal_btn().'
|
|
</model-viewer>
|
|
</model-viewer-preview>';
|
|
|
|
if ($this->isPremiumPlan) {
|
|
$html = $this->premiumHandler->premium_render_ar($html, $this->settings);
|
|
}
|
|
$html .= '</div>';
|
|
|
|
if ($this->settings['modal']) {
|
|
$html = $this->append_modal($html, 'ar-product-modal');
|
|
};
|
|
if($desktopModalOn){
|
|
return $html . $view_in_ar_desktop_modal;
|
|
}
|
|
return $html;
|
|
}
|
|
|
|
private function append_modal($html, $id )
|
|
{
|
|
$branding = $this->addBranding();
|
|
return '<div id='.$id.' class="ar-model-viewer-modal">
|
|
<div class="modal-pop-up">
|
|
<span class="close">×</span>
|
|
<div class="modal-body">
|
|
<div class="ar-modal-content">'. $html .'</div>'
|
|
.($branding !== '' ? '<div class="ar-modal-content-footer">'.$branding.'</div>' : '').
|
|
'</div>
|
|
</div>
|
|
</div>';
|
|
}
|
|
|
|
private function addBranding()
|
|
{
|
|
if ($this->isPremiumPlan) {
|
|
if ($this->settingsOptions[AR_Model_Viewer_Settings_Page::REMOVE_BRAND_KEY] == 'on') {
|
|
return '';
|
|
}
|
|
}
|
|
$html = '<hr class="ar-modal-separator"/>';
|
|
$html .= '<a href="https://bitbute.tech/ar-model-viewer/" target="_blank"><img class="ar-bitbute-logo" src="' . plugins_url('../../assets/bitbute-logo.png', __FILE__) . '" alt="Bitbute logo"></a>';
|
|
return $html;
|
|
}
|
|
|
|
private function setAutoPlayAnimation(){
|
|
$autoPlayAnimation = $this->settingsOptions[AR_Model_Viewer_Settings_Page::AUTO_PLAY_ANIMATION] == 'on';
|
|
$this->defaultAttributes['autoPlay'] = $autoPlayAnimation;
|
|
}
|
|
|
|
private function showDesktopModalBtn()
|
|
{
|
|
if(!$this->isPremiumPlan){
|
|
return false;
|
|
}
|
|
return $this->settingsOptions[AR_Model_Viewer_Settings_Page::REMOVE_DESKTOP_MODAL] != 'on';
|
|
}
|
|
|
|
private function getDesktopModalText()
|
|
{
|
|
return $this->settingsOptions[AR_Model_Viewer_Settings_Page::DESKTOP_MODAL_DESCRIPTION];
|
|
}
|
|
|
|
private function get_attributes_string()
|
|
{
|
|
|
|
$attributes = '';
|
|
foreach ($this->modelAttributes as $key => $value) {
|
|
if ($value) {
|
|
if (is_bool($value)) {
|
|
$attributes .= ' ' . $key;
|
|
} else {
|
|
$attributes .= ' ' . $key . '=' . $value;
|
|
}
|
|
}
|
|
};
|
|
return $attributes;
|
|
}
|
|
|
|
private function get_styles_string()
|
|
{
|
|
$styles = '';
|
|
foreach ($this->defaultStyles as $key => $value) {
|
|
if ($value) {
|
|
$styles .= '; ' . $key . ':' . $value;
|
|
}
|
|
};
|
|
return $styles;
|
|
}
|
|
|
|
private function get_desktop_ar_modal_btn () {
|
|
if($this->showDesktopModalBtn()){
|
|
return '<div class="view-in-ar-desktop-btn">
|
|
<svg version="1.1" id="view_x5F_in_x5F_AR_x5F_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
|
<rect id="Bounding_Box" x="0" y="0" fill="none" width="24" height="24"></rect>
|
|
<g id="Art_layer">
|
|
<path d="M3,4c0-0.55,0.45-1,1-1h2V1H4C2.35,1,1,2.35,1,4v2h2V4z"></path>
|
|
<path d="M20,3c0.55,0,1,0.45,1,1v2h2V4c0-1.65-1.35-3-3-3h-2v2H20z"></path>
|
|
<path d="M4,21c-0.55,0-1-0.45-1-1v-2H1v2c0,1.65,1.35,3,3,3h2v-2H4z"></path>
|
|
<path d="M20,21c0.55,0,1-0.45,1-1v-2h2v2c0,1.65-1.35,3-3,3h-2v-2H20z"></path>
|
|
<g>
|
|
<path d="M18.25,7.6l-5.5-3.18c-0.46-0.27-1.04-0.27-1.5,0L5.75,7.6C5.29,7.87,5,8.36,5,8.9v6.35c0,0.54,0.29,1.03,0.75,1.3
|
|
l5.5,3.18c0.46,0.27,1.04,0.27,1.5,0l5.5-3.18c0.46-0.27,0.75-0.76,0.75-1.3V8.9C19,8.36,18.71,7.87,18.25,7.6z M7,14.96v-4.62
|
|
l4,2.32v4.61L7,14.96z M12,10.93L8,8.61l4-2.31l4,2.31L12,10.93z M13,17.27v-4.61l4-2.32v4.62L13,17.27z"></path>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>';
|
|
}
|
|
}
|
|
} |