ru-se.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

Companion.php (42048B)


      1 <?php
      2 
      3 namespace Materialis;
      4 
      5 class Companion
      6 {
      7 
      8     private static $instance = null;
      9     private static $functionsFiles = array();
     10 
     11     private $_customizer = null;
     12 
     13     private $cpData = array();
     14     private $remoteDataURL = null;
     15 
     16     private $theme = null;
     17     public $themeName = null;
     18     private $themeSlug = null;
     19     public $version = null;
     20     private $path = null;
     21 
     22     private $getCustomizerDataCache = array();
     23 
     24 
     25     private $__configsLoaded = array();
     26 
     27     public function __construct($root = null)
     28     {
     29         $theme           = wp_get_theme();
     30         $this->themeName = $theme->get('Name');
     31         $this->path      = $root;
     32 
     33         // check for current theme in customize.php
     34         if ($previewedTheme = $this->checkForThemePreviewedInCustomizer()) {
     35             $this->themeSlug = $previewedTheme["TextDomain"];
     36             $this->themeName = $previewedTheme["Name"];
     37         } else {
     38             // current theme is a child theme
     39             if ($this->theme->get('Template')) {
     40                 $template          = $this->theme->get('Template');
     41                 $templateThemeData = wp_get_theme($template);
     42                 $this->themeSlug   = $templateThemeData->get('TextDomain');
     43                 $this->themeName   = $templateThemeData->get('Name');
     44             } else {
     45                 $this->themeSlug = $this->theme->get('TextDomain');
     46             }
     47 
     48         }
     49 
     50         if ( ! $this->isCurrentThemeSupported()) {
     51             return;
     52         }
     53 
     54         if (file_exists($this->themeDataPath("/functions.php"))) {
     55             require_once $this->themeDataPath("/functions.php");
     56         }
     57 
     58         if (file_exists($this->themeDataPath("/integrations/index.php"))) {
     59             require_once $this->themeDataPath("/integrations/index.php");
     60         }
     61 
     62         if ( ! self::$instance) {
     63             self::$instance = $this;
     64             add_action('init', array($this, 'initCompanion'));
     65             $this->registerActivationHooks();
     66         } else {
     67             global $wp_customize;
     68             if ($wp_customize && ! $this->isCustomizePreview()) {
     69             add_filter('cloudpress\companion\cp_data', array($this, 'getInstanceData'));
     70         }
     71         }
     72 
     73         $this->version = $this->getCustomizerData('version');
     74     }
     75 
     76     public function checkForThemePreviewedInCustomizer()
     77     {
     78         $theme                   = false;
     79         $is_customize_admin_page = (is_admin() && 'customize.php' == basename($_SERVER['PHP_SELF']));
     80         $keys                    = array('changeset_uuid', 'customize_changeset_uuid', 'customize_theme', 'theme', 'customize_messenger_channel', 'customize_autosaved');
     81         $input_vars              = array_merge(
     82             wp_array_slice_assoc($_GET, $keys),
     83             wp_array_slice_assoc($_POST, $keys)
     84         );
     85 
     86         if ($is_customize_admin_page && isset($input_vars['theme'])) {
     87             $theme = $input_vars['theme'];
     88         } else if (isset($input_vars['customize_theme'])) {
     89             $theme = $input_vars['customize_theme'];
     90         }
     91 
     92         $themeData  = wp_get_theme($theme);
     93         $textDomain = $themeData->get('TextDomain');
     94         $name       = $themeData->get('Name');
     95 
     96         if ($themeData->get('Template')) {
     97             $parentThemeData = wp_get_theme($themeData->get('Template'));
     98             $textDomain      = $parentThemeData->get('TextDomain');
     99             $name            = $parentThemeData->get('Name');
    100         }
    101 
    102         return array(
    103             'TextDomain' => $textDomain,
    104             'Name'       => $name,
    105         );
    106     }
    107 
    108     public function registerActivationHooks()
    109     {
    110         $self = $this;
    111 
    112         register_activation_hook($this->path, function () use ($self) {
    113             do_action('cloudpress\companion\activated\\' . $self->getThemeSlug(), $self);
    114         });
    115 
    116         register_deactivation_hook($this->path, function () use ($self) {
    117             do_action('cloudpress\companion\deactivated\\' . $self->getThemeSlug(), $self);
    118         });
    119     }
    120 
    121     public function setPageContent($data, $filter_context)
    122     {
    123         $status = $filter_context['status'];
    124 
    125         $pages_content = false;
    126         
    127         $data_key = "materialis-pro::page_content";
    128         
    129         if (isset($data[$data_key])) {
    130             $pages_content = $data[$data_key];
    131         } else {
    132             if (isset($data["materialis::page_content"])) {
    133                 $data_key      = "materialis::page_content";
    134                 $pages_content = $data[$data_key];;
    135             }
    136         }
    137         
    138         if ($status == "draft" && $pages_content) {
    139             $page_id = isset($_POST['customize_post_id']) ? intval($_POST['customize_post_id']) : -1;
    140 
    141             $encode        = false;
    142             $pages_content = $pages_content["value"];
    143             if (is_string($pages_content)) {
    144                 $pages_content = json_decode(urldecode($pages_content), true);
    145                 $encode        = true;
    146             }
    147 
    148             $page_content = $pages_content[$page_id];
    149             $page_content = preg_replace('/<!--@@CPPAGEID\[(.*)\]@@-->/s', '', $page_content);
    150 
    151             if ($page_id != -1) {
    152 
    153                 $post = get_post($page_id);
    154 
    155                 wp_create_post_autosave(array(
    156                     'post_ID'      => $page_id,
    157                     'post_content' => $page_content,
    158                     'post_title'   => $post->post_title,
    159                 ));
    160 
    161                 //unset($pages_content[$page_id]);
    162 
    163                 if ($encode) {
    164                     $data[$data_key]["value"] = json_encode($pages_content);
    165                 } else {
    166                     $data[$data_key]["value"] = $pages_content;
    167                 }
    168 
    169             }
    170         }
    171 
    172         do_action('cloudpress\companion\clear_caches');
    173         
    174         return $data;
    175     }
    176 
    177     public function initCompanion()
    178     {
    179 
    180         $this->checkNotifications();
    181 
    182         $this->checkIfCompatibleChildTheme();
    183 
    184         $this->_customizer = new \Materialis\Customizer\Customizer($this);
    185         \Materialis\Customizer\Template::load($this);
    186         \Materialis\Customizer\ThemeSupport::load();
    187 
    188         add_action('wp_ajax_create_home_page', array($this, 'createFrontPage'));
    189 
    190         add_action('wp_ajax_cp_open_in_customizer', array($this, 'openPageInCustomizer'));
    191         add_action('wp_ajax_cp_shortcode_refresh', array($this, 'shortcodeRefresh'));
    192 
    193         add_filter('page_row_actions', array($this, 'addEditInCustomizer'), 0, 2);
    194 
    195         add_action('admin_footer', array($this, 'addAdminScripts'));
    196 
    197         add_action('media_buttons', array($this, 'addEditInCustomizerPageButtons'));
    198 
    199         add_filter('is_protected_meta', array($this, 'isProtectedMeta'), 10, 3);
    200 
    201         add_filter("customize_changeset_save_data", array($this, 'setPageContent'), -10, 2);
    202 
    203         // loadKirkiCss Output Components;
    204         $this->setKirkiOutputFields();
    205 
    206         // look for google fonts
    207         $this->addGoogleFonts();
    208 
    209         do_action('cloudpress\companion\ready', $this);
    210 
    211         add_action('customize_register', function ($wp_customize) {
    212             \Materialis\KirkiControls\SectionSettingControl::load();
    213             $wp_customize->register_control_type("Materialis\\KirkiControls\\SectionSettingControl");
    214 
    215             add_filter('kirki/control_types', function ($controls) {
    216 
    217                 if (class_exists("Materialis\\KirkiControls\\SectionSettingControl")) {
    218                     $controls['sectionsetting'] = "Materialis\\KirkiControls\\SectionSettingControl";
    219                 }
    220 
    221                 return $controls;
    222             });
    223 
    224         });
    225 
    226         // add post meta revisions (to revert from a page editable back to normal);
    227         $this->addMaintainableMetaToRevision();
    228     }
    229 
    230     public function getMaintainableKeysLabelPair($fields = array())
    231     {
    232         $fields = array_merge($fields, array(
    233             'is_' . $this->themeSlug . '_front_page'        => 'Is ' . $this->themeName . ' Front Page',
    234             'is_' . $this->themeSlug . '_maintainable_page' => 'Is ' . $this->themeName . ' FMaintainable Page',
    235         ));
    236 
    237         return $fields;
    238     }
    239 
    240     public function getMaintainableMetaKeys()
    241     {
    242         $keys = $this->getMaintainableKeysLabelPair();
    243 
    244         return array_keys($keys);
    245 
    246     }
    247 
    248     public function addMaintainableMetaToRevision()
    249     {
    250         $keys = $this->getMaintainableMetaKeys();
    251         foreach ($keys as $key) {
    252             add_filter("_wp_post_revision_field_{$key}", array($this, 'getMetaFieldRevision'), 10, 2);
    253         }
    254 
    255 //        add_filter('_wp_post_revision_fields', array($this, 'getMaintainableKeysLabelPair'));
    256         add_action('save_post', array($this, 'saveMetaFieldRevision'), 10, 2);
    257         add_action('wp_restore_post_revision', array($this, 'restoreMetaFieldRevision'), 10, 2);
    258 
    259     }
    260 
    261     public function getMetaFieldRevision($value, $field)
    262     {
    263         global $revision;
    264 
    265         return get_metadata('post', $revision->ID, $field, true);
    266 
    267     }
    268 
    269     public function saveMetaFieldRevision($post_id, $post)
    270     {
    271         if ($parent_id = wp_is_post_revision($post_id)) {
    272 
    273             $parent = get_post($parent_id);
    274 
    275             $keys = $this->getMaintainableMetaKeys();
    276             foreach ($keys as $key) {
    277                 $meta_value = get_post_meta($parent->ID, $key, true);
    278                 if ($meta_value) {
    279                     add_metadata('post', $post_id, $key, $meta_value);
    280                 }
    281             }
    282         }
    283     }
    284 
    285     public function restoreMetaFieldRevision($post_id, $revision_id)
    286     {
    287         if ($parent_id = wp_is_post_revision($revision_id)) {
    288 
    289             $keys = $this->getMaintainableMetaKeys();
    290             foreach ($keys as $key) {
    291                 $meta_value = get_metadata('post', $revision_id, $key, true);
    292 
    293                 if ($meta_value) {
    294                     update_post_meta($post_id, $key, $meta_value);
    295                 } else {
    296                     delete_post_meta($post_id, $key);
    297                 }
    298             }
    299         }
    300     }
    301 
    302     public function checkNotifications()
    303     {
    304         $notifications = $this->themeDataPath("/notifications.php");
    305         if (file_exists($notifications)) {
    306             $notifications = require_once $notifications;
    307         } else {
    308             $notifications = array();
    309         }
    310 
    311         \Materialis\Notify\NotificationsManager::load($notifications);
    312     }
    313 
    314     public function setKirkiOutputFields()
    315     {
    316         global $wp_customize;
    317 
    318         if ( ! class_exists("\Kirki")) {
    319             return;
    320         }
    321 
    322         // is managed in customizer;
    323         if ($wp_customize) {
    324             return;
    325         }
    326 
    327         $settings = (array)$this->getCustomizerData("customizer:settings");
    328 
    329         foreach ($settings as $id => $data) {
    330             $controlClass = self::getTreeValueAt($data, "control:class", "");
    331             if (strpos($controlClass, "kirki:") === 0 && self::getTreeValueAt($data, "control:wp_data:output")) {
    332                 $configArgs = self::getTreeValueAt($data, "wp_data", array());
    333                 \Kirki::add_config($id, $configArgs);
    334 
    335                 $fieldArgs             = self::getTreeValueAt($data, "control:wp_data", array());
    336                 $fieldArgs['type']     = str_replace("kirki:", "", $controlClass);
    337                 $fieldArgs['settings'] = $id;
    338                 $fieldArgs['section']  = self::getTreeValueAt($data, "section");
    339 
    340                 if ( ! isset($fieldArgs['default'])) {
    341                     $fieldArgs['default'] = self::getTreeValueAt($data, "wp_data:default", array());
    342                 }
    343 
    344                 \Kirki::add_field($id, $fieldArgs);
    345             }
    346         }
    347 
    348     }
    349 
    350     public function loadJSON($path)
    351     {
    352 
    353         if ( ! file_exists($path)) {
    354             return array();
    355         }
    356 
    357         $content = file_get_contents($path);
    358 
    359         return json_decode($content, true);
    360     }
    361 
    362     public function loadConfig($path, $default = array())
    363     {
    364 
    365         if (isset($this->__configsLoaded[$path])) {
    366             return $this->__configsLoaded[$path];
    367         }
    368 
    369         if ( ! file_exists($path)) {
    370             return $default;
    371         }
    372 
    373         $content = require $path;
    374 
    375         $this->__configsLoaded[$path] = $content;
    376 
    377         return $content;
    378     }
    379 
    380     public function requireCPData($filter = true)
    381     {
    382         $cpData = get_theme_mod('theme_options', null);
    383         if ( ! $cpData) {
    384             $site = site_url();
    385             $site = preg_replace("/http(s)?:\/\//", "", $site);
    386             $key  = get_theme_mod('theme_pro_key', 'none');
    387 
    388             $cpData = $this->loadJSON($this->themeDataPath("/data.json"));
    389 
    390             if ( ! $cpData) {
    391                 if ($this->remoteDataURL) {
    392                     require_once ABSPATH . WPINC . "/pluggable.php";
    393 
    394                     $url = $this->remoteDataURL . "/" . $this->themeSlug;
    395 
    396                     // allow remote url
    397                     add_filter('http_request_args', function ($r, $_url) use ($url) {
    398                         if ($url === $_url) {
    399                             $r['reject_unsafe_urls'] = false;
    400                         }
    401 
    402                         return $r;
    403                     }, 10, 2);
    404 
    405                     $data = wp_safe_remote_get(
    406                         $url,
    407                         array(
    408                             'method'      => 'GET',
    409                             'timeout'     => 45,
    410                             'redirection' => 5,
    411                             'blocking'    => true,
    412                             'httpversion' => '1.0',
    413                             'body'        => array(
    414                                 'site' => $site,
    415                                 'key'  => $key,
    416                             ),
    417                         )
    418                     );
    419                     if ($data instanceof \WP_Error) {
    420                         //TODO: Add a nicer message here
    421                         ob_get_clean();
    422                         wp_die('There was an issue connecting to the theme server. Please contact the theme support!');
    423                     } else {
    424                         //TODO: Load remote data
    425                         // $cpData = {};
    426                         // set_theme_mod('theme_options',$this->cpData);
    427                     }
    428                 }
    429             }
    430         }
    431 
    432         if ($filter) {
    433             $cpData = apply_filters("cloudpress\companion\cp_data", $cpData, $this);
    434         }
    435 
    436         $this->cpData = $cpData;
    437 
    438         return $cpData;
    439     }
    440 
    441     public function getInstanceData()
    442     {
    443         return $this->requireCPData(false);
    444     }
    445 
    446     public function getCustomizerData($key = null, $filter = true)
    447     {
    448         if (isset($this->getCustomizerDataCache[$key])) {
    449             return $this->getCustomizerDataCache[$key];
    450         }
    451 
    452         if ( ! is_array($this->cpData)) {
    453             return array();
    454         }
    455 
    456         $this->requireCPData($filter);
    457 
    458         if ($key === null) {
    459             return $this->cpData;
    460         }
    461 
    462         $result = self::getTreeValueAt($this->cpData, $key);
    463 
    464         $this->getCustomizerDataCache[$key] = $result;
    465 
    466         return $result;
    467     }
    468 
    469     public function isCurrentThemeSupported()
    470     {
    471         $supportedThemes = (array)$this->getCustomizerData('themes', false);
    472         $currentTheme    = $this->themeSlug;
    473 
    474         $supported = (in_array($currentTheme, $supportedThemes) || in_array('*', $supportedThemes));
    475 
    476         return $supported;
    477     }
    478 
    479     public function checkIfCompatibleChildTheme()
    480     {
    481         $theme    = wp_get_theme();
    482         $response = false;
    483         if ($theme && $theme->get('Template')) {
    484             $template = $theme->get('Template');
    485 
    486             if (in_array($template, $this->getCustomizerData('themes'))) {
    487                 add_filter('cloudpress\customizer\supports', "__return_true");
    488                 $response = true;
    489             }
    490 
    491         }
    492 
    493         return $response;
    494     }
    495 
    496     public function isMaintainable($post_id = false)
    497     {
    498 
    499         if ( ! $post_id) {
    500             global $post;
    501             $post_id = ($post && property_exists($post, "ID")) ? $post->ID : false;
    502         }
    503 
    504         if ( ! $post_id) {
    505             return false;
    506         }
    507 
    508         $result = (
    509             ('1' === get_post_meta($post_id, 'is_' . $this->themeSlug . '_front_page', true))
    510             || ('1' === get_post_meta($post_id, 'is_' . $this->themeSlug . '_maintainable_page', true))
    511         );
    512 
    513         $result = $result || $this->applyOnPrimaryLanguage($post_id, array($this, 'isMaintainable'));
    514 
    515         return $result;
    516     }
    517 
    518     public function isProtectedMeta($protected, $meta_key, $meta_type)
    519     {
    520         $is_protected = array(
    521             'is_' . $this->themeSlug . '_front_page',
    522             'is_' . $this->themeSlug . '_maintainable_page',
    523         );
    524         if (in_array($meta_key, $is_protected)) {
    525             return true;
    526         }
    527 
    528         return $protected;
    529     }
    530 
    531     public function isMultipage()
    532     {
    533         return $this->getCustomizerData('theme_type') === "multipage";
    534     }
    535 
    536     public function getCurrentPageId()
    537     {
    538         global $post;
    539         $post_id = ($post && property_exists($post, "ID")) ? $post->ID : false;
    540 
    541         if ( ! $post_id) {
    542             return false;
    543         }
    544 
    545         $editablePostTypes = apply_filters('cloudpress\companion\editable_post_types', array("page"));
    546 
    547         if ( ! in_array($post->post_type, $editablePostTypes)) {
    548             return false;
    549         }
    550 
    551         return $post_id;
    552     }
    553 
    554     private function applyOnPrimaryLanguage($post_id, $callback)
    555     {
    556         $result = false;
    557         global $post;
    558 
    559         if (function_exists('pll_get_post') && function_exists('pll_default_language')) {
    560             $slug      = pll_default_language('slug');
    561             $defaultID = pll_get_post($post_id, $slug);
    562             $sourceID  = isset($_REQUEST['from_post']) ? $_REQUEST['from_post'] : null;
    563             $defaultID = $defaultID ? $defaultID : $sourceID;
    564 
    565             if ($defaultID && ($defaultID !== $post_id)) {
    566                 $result = call_user_func($callback, $defaultID);
    567             }
    568         }
    569 
    570         global $sitepress;
    571         if ($sitepress) {
    572             $defaultLanguage = $sitepress->get_default_language();
    573             global $wpdb;
    574 
    575             $sourceTRID = isset($_REQUEST['trid']) ? $_REQUEST['trid'] : null;
    576             $trid       = $sitepress->get_element_trid($post_id);
    577             $trid       = $trid ? $trid : $sourceTRID;
    578             $defaultID  = $wpdb->get_var(
    579                 $wpdb->prepare(
    580                     "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND language_code=%s",
    581                     $trid,
    582                     $defaultLanguage));
    583 
    584             if ($defaultID && ($defaultID !== $post_id)) {
    585                 $result = call_user_func($callback, $defaultID);
    586             }
    587         }
    588 
    589         return $result;
    590     }
    591 
    592     public function isFrontPage($post_id = false)
    593     {
    594 
    595         if ( ! $post_id) {
    596             global $post;
    597             $post_id = ($post && property_exists($post, "ID")) ? $post->ID : false;
    598         }
    599 
    600         if ( ! $post_id) {
    601             return false;
    602         }
    603 
    604         $isFrontPage = '1' === get_post_meta($post_id, 'is_' . $this->themeSlug . '_front_page', true);
    605 
    606         $isWPFrontPage = is_front_page() && ! is_home();
    607 
    608         if ($isWPFrontPage && ! $isFrontPage && $this->isMaintainable($post_id)) {
    609             update_post_meta($post_id, 'is_' . $this->themeSlug . '_front_page', '1');
    610             delete_post_meta($post_id, 'is_' . $this->themeSlug . '_maintainable_page');
    611             $isFrontPage = true;
    612         }
    613 
    614         $isFrontPage = $isFrontPage || $this->applyOnPrimaryLanguage($post_id, array($this, 'isFrontPage'));
    615 
    616         return $isFrontPage;
    617     }
    618 
    619     public function getFrontPage()
    620     {
    621         $query = new \WP_Query(
    622             array(
    623                 "post_status" => "publish",
    624                 "post_type"   => 'page',
    625                 "meta_key"    => 'is_' . $this->themeSlug . '_front_page',
    626             )
    627         );
    628         if (count($query->posts)) {
    629             return $query->posts[0];
    630         }
    631 
    632         return null;
    633     }
    634 
    635     public function loadMaintainablePageAssets($post, $template)
    636     {
    637         do_action('cloudpress\template\load_assets', $this, $post, $template);
    638     }
    639 
    640     public function rootPath()
    641     {
    642         return dirname($this->path);
    643     }
    644 
    645     public function rootURL()
    646     {
    647         $templateDir = wp_normalize_path(get_stylesheet_directory());
    648         $pluginDir   = wp_normalize_path(plugin_dir_path($this->path));
    649         $path        = wp_normalize_path($this->path);
    650         $url         = site_url();
    651         if (strpos($path, $templateDir) === 0) {
    652             $path = dirname($path);
    653             $abs  = wp_normalize_path(ABSPATH);
    654             $path = str_replace($abs, '/', $path);
    655             $url  = get_stylesheet_directory_uri() . $path;
    656         } else {
    657             $url = plugin_dir_url($this->path);
    658         }
    659 
    660         return untrailingslashit($url);
    661     }
    662 
    663     public function themeDataPath($rel = "")
    664     {
    665         return $this->rootPath() . "/theme-data/" . $this->themeSlug . $rel;
    666     }
    667 
    668     public function themeDataURL($rel = "")
    669     {
    670         return $this->rootURL() . "/theme-data/" . $this->themeSlug . $rel;
    671     }
    672 
    673     public function assetsRootURL()
    674     {
    675         return $this->rootURL() . "/assets";
    676     }
    677 
    678     public function assetsRootPath()
    679     {
    680         return $this->rootPath() . "/assets";
    681     }
    682 
    683     public function customizer()
    684     {
    685         return $this->_customizer;
    686     }
    687 
    688     public function getThemeSlug($as_fn_prefix = false)
    689     {
    690         $slug = $this->themeSlug;
    691 
    692         if ($as_fn_prefix) {
    693             $slug = str_replace("-", "_", $slug);
    694         }
    695 
    696         return $slug;
    697     }
    698 
    699     public function __createFrontPage()
    700     {
    701         $page = $this->getFrontPage();
    702 
    703         update_option($this->themeSlug . '_companion_old_show_on_front', get_option('show_on_front'));
    704         update_option($this->themeSlug . '_companion_old_page_on_front', get_option('page_on_front'));
    705 
    706         if ( ! $page) {
    707             $content = apply_filters('cloudpress\companion\front_page_content', "", $this);
    708 
    709             $post_id = wp_insert_post(
    710                 array(
    711                     'comment_status' => 'closed',
    712                     'ping_status'    => 'closed',
    713                     'post_name'      => $this->themeName,
    714                     'post_title'     => 'Front Page',
    715                     'post_status'    => 'publish',
    716                     'post_type'      => 'page',
    717                     'page_template'  => apply_filters('cloudpress\companion\front_page_template', "page-templates/homepage.php"),
    718                     'post_content'   => $content,
    719                 )
    720             );
    721 
    722             set_theme_mod($this->themeSlug . '_page_content', $content);
    723             update_option('show_on_front', 'page');
    724             update_option('page_on_front', $post_id);
    725             update_post_meta($post_id, 'is_' . $this->themeSlug . '_front_page', "1");
    726 
    727             if (null == get_page_by_title('Blog')) {
    728                 $post_id = wp_insert_post(
    729                     array(
    730                         'comment_status' => 'closed',
    731                         'ping_status'    => 'closed',
    732                         'post_name'      => 'blog',
    733                         'post_title'     => 'Blog',
    734                         'post_status'    => 'publish',
    735                         'post_type'      => 'page',
    736                     )
    737                 );
    738             }
    739 
    740             $blog = get_page_by_title('Blog');
    741             update_option('page_for_posts', $blog->ID);
    742         } else {
    743             update_option('show_on_front', 'page');
    744             update_option('page_on_front', $page->ID);
    745             update_post_meta($page->ID, 'is_' . $this->themeSlug . '_front_page', "1");
    746         }
    747     }
    748 
    749     public function createFrontPage()
    750     {
    751         $nonce = @$_POST['create_home_page_nounce'];
    752         if ( ! wp_verify_nonce($nonce, 'create_home_page_nounce')) {
    753             die();
    754         }
    755 
    756         $this->__createFrontPage();
    757     }
    758 
    759     public function restoreFrontPage()
    760     {
    761         if ($this->getFrontPage()) {
    762             update_option('show_on_front', get_option($this->themeSlug . '_companion_old_show_on_front'));
    763             update_option('page_on_front', get_option($this->themeSlug . '_companion_old_page_on_front'));
    764         }
    765     }
    766 
    767     public function isWCPage($post)
    768     {
    769         if (function_exists('wc_get_page_id')) {
    770             $shopId      = wc_get_page_id('shop');
    771             $cartId      = wc_get_page_id('cart');
    772             $checkoutId  = wc_get_page_id('checkout');
    773             $myaccountId = wc_get_page_id('myaccount');
    774 
    775             switch ($post->ID) {
    776                 case $shopId:
    777                 case $cartId:
    778                 case $checkoutId:
    779                 case $myaccountId:
    780                     return true;
    781                     break;
    782                 default:
    783                     return false;
    784 
    785             }
    786 
    787         } else {
    788             return false;
    789         }
    790     }
    791 
    792     public function canEditInCustomizer($post = null)
    793     {
    794         $canEdit = false;
    795 
    796         if ( ! $post) {
    797             global $post;
    798         }
    799 
    800         if (is_numeric($post)) {
    801             $post = get_post($post);
    802         }
    803 
    804         $editablePostTypes = apply_filters('cloudpress\companion\editable_post_types', array("page"));
    805 
    806         if ( ! $post || ! in_array($post->post_type, $editablePostTypes)) {
    807             return false;
    808         } else {
    809             if ($this->isWCPage($post)) {
    810                 return false;
    811             } else {
    812                 if ($this->isMaintainable($post->ID) || $this->isFrontPage($post->ID)) {
    813                     $canEdit = true;
    814                 }
    815             }
    816         }
    817 
    818         return apply_filters('cloudpresss\companion\can_edit_in_customizer', $canEdit, $post);
    819 
    820     }
    821 
    822     public function addEditInCustomizer($actions, $post)
    823     {
    824         if ($this->canEditInCustomizer($post)) {
    825 
    826             $actions = array_merge(
    827                 array(
    828                     "cp_page_builder" => '<a href="javascript:void();" onclick="cp_open_page_in_customizer(' . $post->ID . ')" >Edit in Customizer</a>',
    829                 ),
    830                 $actions
    831             );
    832         }
    833 
    834         return $actions;
    835     }
    836 
    837     public function addEditInCustomizerPageButtons()
    838     {
    839         global $post;
    840 
    841         if ($this->canEditInCustomizer($post)) {
    842             echo '<a href="javascript:void();"  onclick="cp_open_page_in_customizer(' . $post->ID . ')"  class="button button-primary">' . __('Edit In Customizer', 'cloudpress-companion') . '</a>';
    843         }
    844     }
    845 
    846     public function addAdminScripts()
    847     {
    848 
    849         ?>
    850 
    851         <style type="text/css">
    852             a:not(.button)[onclick*="cp_open_page_"] {
    853                 background-color: #0073aa;
    854                 color: #ffffff;
    855                 padding: 0.2em 0.8em;
    856                 line-height: 150%;
    857                 border-radius: 4px;
    858                 display: inline-block;
    859                 text-transform: uppercase;
    860                 font-size: 0.82em;
    861             }
    862 
    863             a:not(.button)[onclick*="cp_open_page_"]:hover {
    864                 background-color: #0081bd;
    865             }
    866         </style>
    867         <?php
    868 
    869         global $post;
    870 
    871         if ( ! $post) {
    872             return;
    873         }
    874 
    875         if ($this->isMultipage()) {
    876 
    877             $title_placeholder = apply_filters('enter_title_here', __('Enter title here', 'materialis'), $post);
    878 
    879             ?>
    880             <style>
    881                 input[name=new-page-name-val] {
    882                     padding: 3px 8px;
    883                     font-size: 1.7em;
    884                     line-height: 100%;
    885                     height: 1.7em;
    886                     width: 100%;
    887                     outline: none;
    888                     margin: 0 0 3px;
    889                     background-color: #fff;
    890                     border-style: solid;
    891                     border-color: #c3c3c3;
    892                     border-width: 1px;
    893                     margin-bottom: 10px;
    894                     margin-top: 10px;
    895                 }
    896 
    897                 input[name=new-page-name-val].error {
    898                     border-color: #f39e9e;
    899                     border-style: solid;
    900                     color: #f39e9e;
    901                 }
    902 
    903                 h1.cp-open-in-custmizer {
    904                     font-size: 23px;
    905                     font-weight: 400;
    906                     margin: 0;
    907                     padding: 9px 0 4px 0;
    908                     line-height: 29px;
    909                 }
    910 
    911             </style>
    912             <div style="display: none;" id="open_page_in_customizer_set_name">
    913                 <h1 class="cp-open-in-custmizer"><?php _e('Set a name for the new page', 'cloudpress-companion'); ?></h1>
    914                 <input placeholder="<?php echo $title_placeholder ?>" class="" name="new-page-name-val"/>
    915                 <button class="button button-primary" name="new-page-name-save"> <?php _e('Set Page Name', 'cloudpress-companion'); ?></button>
    916             </div>
    917             <script>
    918                 function cp_open_page_in_customizer(page) {
    919 
    920                     var isAutodraft = jQuery('[name="original_post_status"]').length ? jQuery('[name="original_post_status"]').val() === "auto-draft" : false;
    921 
    922                     function doAjaxCall(pageName) {
    923                         var data = {
    924                             action: 'cp_open_in_customizer',
    925                             page: page
    926                         };
    927 
    928                         if (pageName) {
    929                             data['page_name'] = pageName;
    930                         }
    931 
    932                         jQuery.post(ajaxurl, data).done(function (response) {
    933 
    934                             window.location = response.trim();
    935                         });
    936                     }
    937 
    938                     if (isAutodraft) {
    939 
    940                         alert("<?php echo __('Page needs to be published before editing it in customizer', 'cloudpress-companion'); ?>");
    941                         return;
    942 
    943                         var title = jQuery('[name="post_title"]').val();
    944                         tb_show('Set Page Name', '#TB_inline?inlineId=open_page_in_customizer_set_name&height=150', false);
    945                         var TB_Window = jQuery('#TB_window').height('auto');
    946 
    947                         var titleInput = TB_Window.find('[name="new-page-name-val"]');
    948 
    949                         titleInput.val(title).on('keypress', function () {
    950                             jQuery(this).removeClass('error');
    951                         });
    952 
    953                         TB_Window.find('[name="new-page-name-save"]').off('click').on('click', function () {
    954                             var newTitle = titleInput.val().trim();
    955                             if (newTitle.length == 0) {
    956                                 titleInput.addClass('error');
    957                                 return;
    958                             } else {
    959                                 doAjaxCall(newTitle);
    960                             }
    961                         });
    962 
    963                     } else {
    964                         doAjaxCall();
    965                     }
    966 
    967                 }
    968             </script>
    969             <?php
    970 
    971         }
    972     }
    973 
    974     public function wrapPostContentInSection($post_id)
    975     {
    976         $post    = get_post($post_id);
    977         $content = $post->post_content;
    978 
    979         if (trim($content)) {
    980 
    981             $content = wpautop($content);
    982 
    983             $content = "<div data-id='initial-content-section' data-export-id='initial-content-section' data-label='Initial Content' id='initial-content-section' class='content-section content-section-spacing'>\n" .
    984                        "   <div class='gridContainer'>\n" .
    985                        "     <div class='row'>\n\n" .
    986                        "        <div class='col-xs-12 col-sm-12'>" .
    987                        "                {$content}\n" .
    988                        "          </div>\n" .
    989                        "      </div>\n" .
    990                        "  </div>\n" .
    991                        "</div>\n";
    992 
    993             if ( ! has_action('pre_post_update', 'wp_save_post_revision')) {
    994                 add_action('pre_post_update', 'wp_save_post_revision');
    995             }
    996 
    997             wp_update_post(array(
    998                 'ID'           => $post_id,
    999                 'post_content' => $content,
   1000             ));
   1001         }
   1002     }
   1003 
   1004     public function openPageInCustomizer()
   1005     {
   1006         $post_id = intval($_REQUEST['page']);
   1007         $toMark  = isset($_REQUEST['mark_as_editable']);
   1008 
   1009         $post = get_post($post_id);
   1010 
   1011         if ($post) {
   1012 
   1013             if ($post->post_status === "auto-draft" || $post->post_status === "draft") {
   1014 
   1015                 /*
   1016                 wp_publish_post($post_id);
   1017 
   1018                 $title    = isset($_REQUEST['page_name']) ? wp_kses_post($_REQUEST['page_name']) : __('Untitled Page - ' . date("Y-m-d H:i:s"), 'cloudpress-companion');
   1019                 $new_slug = sanitize_title($title);
   1020                 wp_update_post(array(
   1021                     'ID'         => $post_id,
   1022                     'post_title' => $title,
   1023                     'post_name'  => $new_slug // do your thing here
   1024             ));*/
   1025             }
   1026 
   1027             $isMarked = get_post_meta($post_id, 'is_' . $this->themeSlug . '_maintainable_page', true);
   1028 
   1029             if ( ! intval($isMarked) && $toMark) {
   1030                 update_post_meta($post_id, 'is_' . $this->themeSlug . '_maintainable_page', "1");
   1031                 $this->wrapPostContentInSection($post_id);
   1032                 $template = get_post_meta($post_id, '_wp_page_template', true);
   1033                 if ( ! $template || $template === "default") {
   1034                     update_post_meta($post_id, '_wp_page_template', apply_filters('materialis_maintainable_default_template', "full-width-page.php"));
   1035                 }
   1036 
   1037                 do_action('cloudpress\ajax\after_maintainable_mark', $post_id);
   1038             }
   1039 
   1040         }
   1041 
   1042         $url = $this->get_page_link($post_id);
   1043 
   1044         ?>
   1045         <?php echo admin_url('customize.php') ?>?url=<?php echo urlencode($url) ?>
   1046         <?php
   1047 
   1048         exit;
   1049     }
   1050 
   1051     public function get_page_link($post_id)
   1052     {
   1053         global $sitepress;
   1054         $url = false;
   1055         if ($sitepress) {
   1056             $url           = get_page_link($post_id);
   1057             $args          = array('element_id' => $post_id, 'element_type' => 'page');
   1058             $language_code = apply_filters('wpml_element_language_code', null, $args);
   1059             $url           = apply_filters('wpml_permalink', $url, $language_code);
   1060         }
   1061 
   1062         if ( ! $url) {
   1063             $url = get_permalink($post_id);
   1064         }
   1065 
   1066         return $url;
   1067     }
   1068 
   1069     public function shortcodeRefresh()
   1070     {
   1071         if ( ! is_user_logged_in() || ! current_user_can('edit_theme_options')) {
   1072             die();
   1073         }
   1074 
   1075         add_filter('materialis_is_shortcode_refresh', '__return_true');
   1076 
   1077         $shortcode = isset($_REQUEST['shortcode']) ? $_REQUEST['shortcode'] : false;
   1078         $context   = isset($_REQUEST['context']) ? $_REQUEST['context'] : array();
   1079 
   1080         if ( ! $shortcode) {
   1081             die();
   1082         }
   1083 
   1084         $shortcode = base64_decode($shortcode);
   1085 
   1086         $query   = isset($context['query']) ? $context['query'] : array();
   1087         $content = "";
   1088 //        $wp_query = new \WP_Query($query);
   1089         if (count($query)) {
   1090             query_posts($query);
   1091             while (have_posts()) {
   1092                 the_post();
   1093                 $content .= do_shortcode($shortcode);
   1094             }
   1095 
   1096             wp_reset_query();
   1097         } else {
   1098             $content .= do_shortcode($shortcode);
   1099         }
   1100 
   1101         die($content);
   1102 
   1103     }
   1104 
   1105     public function addGoogleFonts()
   1106     {
   1107         $self = $this;
   1108 
   1109         /**
   1110          * Add preconnect for Google Fonts.
   1111          */
   1112         add_filter('wp_resource_hints', function ($urls, $relation_type) use ($self) {
   1113             if (wp_style_is($self->getThemeSlug() . '-fonts', 'queue') && 'preconnect' === $relation_type) {
   1114                 $urls[] = array(
   1115                     'href' => 'https://fonts.gstatic.com',
   1116                     'crossorigin',
   1117                 );
   1118             }
   1119 
   1120             return $urls;
   1121         }, 10, 2);
   1122 
   1123 
   1124     }
   1125 
   1126 
   1127     // SINGLETON
   1128 
   1129     public static function instance()
   1130     {
   1131         return self::$instance;
   1132     }
   1133 
   1134     public static function letToNum($size)
   1135     {
   1136         $l   = substr($size, -1);
   1137         $ret = substr($size, 0, -1);
   1138         switch (strtoupper($l)) {
   1139             case 'P':
   1140                 $ret *= 1024;
   1141             case 'T':
   1142                 $ret *= 1024;
   1143             case 'G':
   1144                 $ret *= 1024;
   1145             case 'M':
   1146                 $ret *= 1024;
   1147             case 'K':
   1148                 $ret *= 1024;
   1149         }
   1150 
   1151         return $ret;
   1152     }
   1153 
   1154     public static function load($pluginFile)
   1155     {
   1156         $currentMemoryLimit = @ini_get('memory_limit');
   1157         $desiredMemory      = '256M';
   1158 
   1159         if ($currentMemoryLimit) {
   1160             if (self::letToNum($currentMemoryLimit) && self::letToNum($desiredMemory)) {
   1161                 @ini_set('memory_limit', $desiredMemory);
   1162             }
   1163         }
   1164 
   1165         new \Materialis\Companion($pluginFile);
   1166     }
   1167 
   1168     public static function getTreeValueAt($tree, $path, $default = null)
   1169     {
   1170         $result   = $tree;
   1171         $keyParts = explode(":", $path);
   1172         if (is_array($result)) {
   1173             foreach ($keyParts as $part) {
   1174                 if ($result && isset($result[$part])) {
   1175                     $result = $result[$part];
   1176                 } else {
   1177                     return $default;
   1178                 }
   1179             }
   1180         }
   1181 
   1182         return $result;
   1183     }
   1184 
   1185     public static function prefixedMod($mod, $prefix = null)
   1186     {
   1187         $prefix = $prefix ? $prefix : self::instance()->getThemeSlug();
   1188         $prefix = str_replace("-", "_", $prefix);
   1189 
   1190         return $prefix . "_" . $mod;
   1191     }
   1192 
   1193     public static function getThemeMod($mod, $default = false)
   1194     {
   1195         global $wp_customize;
   1196 
   1197         if ($wp_customize) {
   1198             $settings = $wp_customize->unsanitized_post_values();
   1199 
   1200             $key = "CP_AUTO_SETTING[" . $mod . "]";
   1201             if (isset($settings[$key])) {
   1202                 return $settings[$key];
   1203             } else {
   1204                 $exists = apply_filters('cloudpress\customizer\temp_mod_exists', false, $mod);
   1205                 if ($exists) {
   1206                     return apply_filters('cloudpress\customizer\temp_mod_content', false, $mod);
   1207                 }
   1208             }
   1209         }
   1210 
   1211         if ($default === false) {
   1212             $default                = self::instance()->getCustomizerData("customizer:settings:{$mod}:wp_data:default");
   1213             $alternativeTextDomains = (array)self::instance()->getCustomizerData('alternativeTextDomains:' . self::instance()->getThemeSlug());
   1214 
   1215             if ( ! $default) {
   1216                 foreach ($alternativeTextDomains as $atd) {
   1217                     $mod     = self::prefixedMod($mod, $atd);
   1218                     $default = self::instance()->getCustomizerData("customizer:settings:{$mod}:wp_data:default");
   1219                     if ($default !== null) {
   1220                         break;
   1221                     }
   1222                 }
   1223             }
   1224         }
   1225 
   1226         $result = $default;
   1227         $temp   = get_theme_mod(self::prefixedMod($mod), "CP_UNDEFINED_THEME_MOD");
   1228         if ($temp !== "CP_UNDEFINED_THEME_MOD") {
   1229             $result = $temp;
   1230         } else {
   1231             $result                 = "CP_UNDEFINED_THEME_MOD";
   1232             $alternativeTextDomains = (array)self::instance()->getCustomizerData('alternativeTextDomains:' . self::instance()->getThemeSlug());
   1233             foreach ($alternativeTextDomains as $atd) {
   1234                 $temp = get_theme_mod(self::prefixedMod($mod, $atd), "CP_UNDEFINED_THEME_MOD");
   1235                 if ($temp !== "CP_UNDEFINED_THEME_MOD") {
   1236                     $result = $temp;
   1237                     break;
   1238                 }
   1239             }
   1240 
   1241             if ($result === "CP_UNDEFINED_THEME_MOD") {
   1242                 $result = get_theme_mod($mod, $default);
   1243             }
   1244         }
   1245 
   1246         return $result;
   1247     }
   1248 
   1249     public static function echoMod($mod, $default = false)
   1250     {
   1251         echo self::getThemeMod($mod, $default);
   1252     }
   1253 
   1254     public static function echoURLMod($mod, $default = false)
   1255     {
   1256         $value = self::getThemeMod($mod, $default);
   1257         $value = str_replace('[tag_companion_uri]', self::instance()->themeDataURL(), $value);
   1258         echo esc_url($value);
   1259     }
   1260 
   1261     public static function filterDefault($data)
   1262     {
   1263         if (is_array($data)) {
   1264             $data = self::filterArrayDefaults($data);
   1265         } else {
   1266             $data = str_replace('[tag_companion_uri]', \Materialis\Companion::instance()->themeDataURL(), $data);
   1267             $data = str_replace('[tag_theme_uri]', get_template_directory_uri(), $data);
   1268 
   1269             $data = str_replace('[tag_companion_dir]', \Materialis\Companion::instance()->themeDataPath(), $data);
   1270             $data = str_replace('[tag_theme_dir]', get_template_directory(), $data);
   1271             $data = str_replace('[tag_style_uri]', get_stylesheet_directory_uri(), $data);
   1272         }
   1273 
   1274         return $data;
   1275     }
   1276 
   1277     public static function filterArrayDefaults($data)
   1278     {
   1279         foreach ($data as $key => $value) {
   1280             $data[$key] = \Materialis\Companion::filterDefault($value);
   1281         }
   1282 
   1283         return $data;
   1284     }
   1285 
   1286     public static function dataURL($path = '')
   1287     {
   1288         return self::instance()->themeDataURL($path);
   1289     }
   1290 
   1291     public static function translateArgs($data)
   1292     {
   1293         if (isset($data['title'])) {
   1294             $data['title'] = __($data['title'], 'cloudpress-companion');
   1295         }
   1296 
   1297         if (isset($data['label'])) {
   1298             $data['label'] = __($data['label'], 'cloudpress-companion');
   1299         }
   1300 
   1301         if (isset($data['choices'])) {
   1302             foreach ($data['choices'] as $key => $value) {
   1303                 if (strpos($value, "#") === false && is_string($key)) {
   1304                     $data['choices'][$key] = __($value, 'cloudpress-companion');
   1305                 }
   1306             }
   1307         }
   1308 
   1309         return $data;
   1310     }
   1311 
   1312     public static function loadJSONFile($path)
   1313     {
   1314         Companion::instance()->loadJSON($path);
   1315     }
   1316 }