<?php
/**
* テーマのコアクラス。
* functions.php で初期化される。
*
* @category includes
* @package mytheme
* @author AD5
*/
class Mytheme {
const PACKAGE_PREFIX = 'MT_';
const INCLUDE_PATH = '/includes/';
const CLASS_FILE_PREFIX = 'class-';
const CONTROLLER_SUFFIX = '_Controller';
const ADMIN_PROCESSOR_PREFIX = 'Admin_Processor_';
const HOOK_CLASSES = array( 'Setting', 'Head', 'Query', 'Activate', 'Admin', 'Cron' );
const ADMIN_PROCS = array( 'setting', 'management' );
private $properties = array();
/**
* 初期化
*/
public function init() {
//タイムゾーンセット
date_default_timezone_set( 'Asia/Tokyo' );
//Built-Inプラグインのロード
include_once( TEMPLATEPATH . '/lib/acf/acf.php' );
include_once( TEMPLATEPATH . '/lib/acf-repeater/acf-repeater.php' );
//クラスファイルのAutoLoad
spl_autoload_register( array( $this, 'autoload' ) );
//各種フックの登録
$this->bind_hook( self::HOOK_CLASSES );
//管理画面の処理
$this->admin_process( self::ADMIN_PROCS );
//コントローラーのルーティング
$this->route_controller();
}
/**
* オートロード(spl_autoload_registerのコールバック)
*/
public function autoload( $class ) {
$directories = array(
TEMPLATEPATH . self::INCLUDE_PATH,
TEMPLATEPATH . self::INCLUDE_PATH . 'controller/',
TEMPLATEPATH . self::INCLUDE_PATH . 'admin/',
TEMPLATEPATH . self::INCLUDE_PATH . 'module/',
TEMPLATEPATH . self::INCLUDE_PATH . 'hooks/',
);
foreach ( $directories as $dir ) {
$class_path = $dir . $this->get_classfile_name( $class );
if ( is_file( $class_path ) ) {
require( $class_path );
return;
}
}
}
/**
* クラス名からクラスファイル名を取得
*/
private function get_classfile_name( $class ) {
$classfile_name = self::CLASS_FILE_PREFIX . strtolower( str_replace( '_', '-', $class ) ) . '.php';
return $classfile_name;
}
/**
* フック用クラスの初期化
*/
public function bind_hook( $hooks ) {
foreach ( $hooks as $hook ) {
$class = self::PACKAGE_PREFIX . $hook;
if ( class_exists( $class ) ) {
$instance = new $class();
if ( method_exists( $instance, 'init' ) ) {
$instance->init();
}
}
}
}
/**
* 管理画面用処理クラスの展開
*/
public function admin_process( $procs ) {
foreach ( $procs as $proc ) {
$class = self::PACKAGE_PREFIX . self::ADMIN_PROCESSOR_PREFIX . $proc;
if ( class_exists( $class ) ) {
$processor = new $class();
if ( method_exists( $processor, 'get_config' ) ) {
$config = $processor->get_config();
if ( ! empty( $config['pages'] ) ) {
$title = ! empty( $config['title'] ) ? $config['title'] : get_bloginfo( 'name' );
$type = ! empty( $config['type'] ) ? $config['type'] : 'manage_option';
$position = ! empty( $config['position'] ) ? $config['position'] : 20;
$parent_slug = "";
foreach ( $config['pages'] as $slug => $page ) {
$page_slug = self::kebab_prefix() . strtolower($proc) . '-' . $slug;
$callback = array( $processor, $slug . '_view' );
//親メニューページの追加
if ( ! $parent_slug ) {
add_action( 'admin_menu', function () use ( $title, $type, $page_slug, $callback, $position ) {
add_menu_page( $title, $title, $type, $page_slug, $callback, '', $position );
} );
$parent_slug = $page_slug;
}
//子メニューページの追加
add_action( 'admin_menu', function () use ( $parent_slug, $type, $page_slug, $callback, $page ) {
$suffix_menu = add_submenu_page( $parent_slug, $page['title'], $page['title'], $type, $page_slug, $callback, '' );
//scriptの追加
if ( ! empty( $page['script'] ) ) {
add_action( "admin_print_scripts-" . $suffix_menu , function () use ( $page ) {
foreach ( $page['script'] as $script ) {
if ( ! empty( $script['path'] ) ) {
wp_enqueue_script( $script['name'], get_template_directory_uri() . $script['path'] );
} else {
wp_enqueue_script( $script['name'] );
}
}
} );
}
//styleの追加
if ( ! empty( $page['style'] ) ) {
add_action( "admin_head-" . $suffix_menu , function () use ( $page ) {
foreach ( $page['style'] as $style ) {
if ( ! empty( $style['path'] ) ) {
wp_enqueue_script( $style['name'], get_template_directory_uri() . $style['path'] );
} else {
wp_enqueue_script( $style['name'] );
}
}
} );
}
} );
//admin_initで実行する処理の追加
if ( ! empty( $page['init_action'] ) ) {
if ( ! empty( $_GET['page'] ) && $_GET['page'] == $page_slug ) {
add_action( 'admin_init', array( $processor, $slug . '_action' ) );
}
}
//オプショングループの追加
if ( ! empty( $page['options'] ) ) {
add_action( 'admin_init', function () use ( $proc, $slug, $page ) {
foreach ( $page['options'] as $option ) {
$group = self::kebab_prefix() . strtolower($proc) . '-' . $slug . '-option-group';
register_setting( $group, $option );
}
} );
}
}
}
}
}
}
}
public static function kebab_prefix() {
return str_replace( '_', '-', strtolower( self::PACKAGE_PREFIX ) );
}
/**
* コントローラのフック
*/
public function route_controller() {
add_action( 'template_include', array( $this, 'apply_controller' ), 9999 );
}
public function apply_controller( $template ) {
$class = self::PACKAGE_PREFIX . strtr( ucwords( strtr( basename( $template, '.php' ), array( '-' => ' ' ) ) ), array( ' ' => '_' ) ) . self::CONTROLLER_SUFFIX;
if ( class_exists( $class ) ) {
$controller = new $class();
global $post;
if ( ! empty( $post->post_name ) && method_exists( $controller, $post->post_name . '_action' ) ) {
$action = $post->post_name . '_action';
} else {
$action = 'index_action';
}
if ( method_exists( $controller, 'init' ) ) {
$controller->init();
}
$return = $controller->$action();
if ( $return ) {
foreach ( $return as $key => $value ) {
$this->properties[$key] = $value;
}
}
}
return $template;
}
public function get( $key ) {
if ( array_key_exists( $key, $this->properties ) ) {
return $this->properties[$key];
} else {
return false;
}
}
}