Ejemplo n.º 1
0
 /**
  * Constructor
  *
  * Throws an exception if config/app.json file is missing.
  *
  * @param $rootPath string The root path to the theme
  *
  * @throws \Exception
  */
 public function __construct($rootPath)
 {
     $this->siteHost = parse_url(site_url(), PHP_URL_HOST);
     $this->httpHost = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null;
     // Load the config
     if (file_exists($rootPath . '/config/app.php')) {
         $this->config = (include $rootPath . '/config/app.php');
     } else {
         if (file_exists($rootPath . '/config/app.json')) {
             $this->config = JSONParser::parse(file_get_contents($rootPath . '/config/app.json'));
         } else {
             throw new \Exception('Missing app.json or app.php configuration for theme.');
         }
     }
     // Create the request object
     $this->request = Request::createFromGlobals();
     $this->environment = getenv('WP_ENV') ?: 'development';
     $this->debug = defined(WP_DEBUG) || $this->environment == 'development';
     // Initialize logging
     $loggingConfig = null;
     if (isset($this->config['logging'])) {
         if (isset($this->config['logging'][$this->environment])) {
             $loggingConfig = $this->config['logging'][$this->environment];
         } else {
             if (isset($this->config['logging']['development'])) {
                 $loggingConfig = $this->config['logging']['development'];
             } else {
                 if (isset($this->config['logging']['other'])) {
                     $loggingConfig = $this->config['logging']['other'];
                 }
             }
         }
     }
     Log::initialize($loggingConfig);
     // Set our text domain, not really used though.
     $this->textdomain = $this->config['text-domain'];
     // Setup our paths
     $this->rootPath = $rootPath;
     $this->classPath = $rootPath . '/classes/';
     if (!file_exists($this->classPath)) {
         $this->classPath = $rootPath . '/Classes/';
         if (!file_exists($this->classPath)) {
             throw new \xception("Missing 'classes' directory in Stem application directory: {$rootPath}");
         }
     }
     // Create the router for extra routes
     $this->router = new Router($this);
     $this->namespace = $this->config['namespace'];
     // Enable/disable XML RPC
     if ($this->setting('options/disable-xml-rpc', false)) {
         add_filter('xmlrpc_enabled', '__return_false', 10000);
     }
     // Enable/disable WordPress JSON API
     if ($this->setting('options/disable-wp-json-api', false)) {
         add_filter('json_enabled', '__return_false', 10000);
         add_filter('json_jsonp_enabled', '__return_false', 10000);
         add_filter('rest_enabled', '__return_false', 10000);
         add_filter('rest_jsonp_enabled', '__return_false', 10000);
         remove_action('xmlrpc_rsd_apis', 'rest_output_rsd');
         remove_action('wp_head', 'rest_output_link_wp_head', 10);
         remove_action('template_redirect', 'rest_output_link_header', 11);
     }
     // Enable/disable WordPress emoji crap
     if ($this->setting('options/disable-wp-json-api', false)) {
         add_action('init', function () {
             remove_action('admin_print_styles', 'print_emoji_styles');
             remove_action('wp_head', 'print_emoji_detection_script', 7);
             remove_action('admin_print_scripts', 'print_emoji_detection_script');
             remove_action('wp_print_styles', 'print_emoji_styles');
             remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
             remove_filter('the_content_feed', 'wp_staticize_emoji');
             remove_filter('comment_text_rss', 'wp_staticize_emoji');
             add_filter('disable-emoji', function ($plugins) {
                 if (is_array($plugins)) {
                     return array_diff($plugins, ['wpemoji']);
                 } else {
                     return [];
                 }
             }, 10000, 1);
         });
     }
     // Enable/disable RSS Feeds
     if ($this->setting('options/disable-rss', false)) {
         add_action('wp_loaded', function () {
             remove_action('wp_head', 'feed_links', 2);
             remove_action('wp_head', 'feed_links_extra', 3);
         });
     }
     // Create the controller/template dispatcher
     $this->dispatcher = new Dispatcher($this);
     // Autoload function for theme classes
     spl_autoload_register(function ($class) {
         if ('\\' == $class[0]) {
             $class = substr($class, 1);
         }
         $class = strtr($class, '\\', DIRECTORY_SEPARATOR);
         $classParts = explode(DIRECTORY_SEPARATOR, $class);
         if (count($classParts) > 1) {
             array_shift($classParts);
             $shortClass = implode(DIRECTORY_SEPARATOR, $classParts);
             if (file_exists($this->classPath . $shortClass . '.php')) {
                 require_once $this->classPath . $shortClass . '.php';
                 return true;
             }
         }
         if (file_exists($this->classPath . $class . '.php')) {
             require_once $this->classPath . $class . '.php';
             return true;
         }
         return false;
     });
     // Theme setup action hook
     add_action('after_setup_theme', function () {
         $this->setup();
     });
     // This does the actual dispatching to Stem controllers
     // and templates.
     add_filter('template_include', function ($template) {
         $this->dispatch();
     });
     // Build the controller map that maps the templates that
     // wordpress is trying to "include" to Controller classes
     // in the stem app/theme.  Additionally, we surface these
     // as "page templates" in the wordpress admin UI.
     if (isset($this->config['page-controllers'])) {
         $this->templates = $this->config['page-controllers'];
         foreach ($this->config['page-controllers'] as $key => $controller) {
             $this->controllerMap[strtolower(preg_replace('|[^aA-zZ0-9_]+|', "-", $key))] = $controller;
         }
         add_filter('theme_page_templates', function ($page_templates, $theme, $post) {
             foreach ($this->config['page-controllers'] as $key => $controller) {
                 $page_templates[preg_replace("/\\s+/", "-", $key) . '.php'] = $key;
             }
             return $page_templates;
         }, 10, 3);
     }
     // Load/save ACF Pro JSON fields to our config directory
     add_filter('acf/settings/save_json', function ($path) use($rootPath) {
         $newpath = $rootPath . '/config/fields';
         if (file_exists($newpath)) {
             return $newpath;
         }
         Log::error("Saving ACF fields, missing {$newpath} directory.");
         return $path;
     });
     add_filter('acf/settings/load_json', function ($paths) use($rootPath) {
         $newpath = $rootPath . '/config/fields';
         if (!file_exists($newpath)) {
             Log::error("Loading ACF fields, missing {$newpath} directory.");
             return $paths;
         }
         unset($paths[0]);
         $paths[] = $newpath;
         return $paths;
     });
     // Load our custom post types
     add_action('init', [$this, 'installCustomPostTypes'], 10000);
     // Require our plugins
     $this->setupRequiredPlugins();
     $this->cacheControl = new CacheControl($this);
     $this->ui = new UI($this);
     $this->admin = new Admin($this);
 }