This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** * Abtract class to be used as a theme template. * Must be implemented before using this class. * There are some special functions that can declared (as protected) in implementations to perform main actions: * - install: (Protected) Additional actions to run when activating the theme (Settings are already created). * - update: (Protected) Actions to update the theme to a new version. (Updating version on DB is done after this). * Takes old theme version as a parameter. Settings are already updated from defaults. * - defaults: (Protected) Returns the default module settings. Used to install, update and fill. * - registerSidebars: The place where to register all theme sidebars by using register_sidebar() function. * - init: (Protected) Actions to run when plugins initialization is performed (on init hook). * - widgetsInit: (Protected) Actions to init theme widgets (In widgets_init). * - startUp: (Protected) Actions to run at system startup (before plugins are loaded). * - _adminMenus: (Hook, must be public) Set the menus in WordPress Dashboard. * * @author Jordi Canals * @package Alkivia * @subpackage Framework * @link http://alkivia.org * @uses akSettings */ abstract class akTheme { /** * Theme ID. Is the theme internal short name. * Filled in constructor (as a constructor param). Used for translations textdomain. * @var string */ protected $ID; /** * Theme style.css main file. * Cointains the full path to the theme style's file considering if it is a child theme. * @var string */ protected $style_file; /** * Theme data. Readed from the main plugin file header and the readme file. * Filled in loadThemeData(). Called in constructor. * From the filename: * - 'ID' - Plugin internal short name. Taken from main plugin's file name. * Fom the file header: * - 'Name' - Name of the theme. * - 'Title' - Long title for the theme. As WP 2.8 is the same as 'Name'. * - 'URI' - Theme's page URI. * - 'Description' - Description of theme's features. * - 'Author' - Author name and link (to author home). * - 'Version' - Theme Version number. * - 'Template' - The parent theme (If this is a child theme). * - 'Tags' - An array of theme tags features. * @var array */ protected $theme_data; /** * Same as $theme_data but for child themes. * * @see akTheme::theme_data * @var array */ protected $child_data = array(); /** * Theme saved data. * - 'post' - Saves the current post. * - 'more' - Saves the read more status. * @var array */ protected $saved; /** * Holds the global 'settings' object. * This object has been created on the framework loader. * @var akSettings */ protected $cfg; /** * Flag to see if we are installing (activating for first time) or reactivating the theme. * @var boolean */ protected $installing = false; /** * Flag to see if theme needs to be updated. * @var boolean */ protected $needs_update = false; /** * Class constructor. * Calls the implementated method 'startUp' if it exists. This is done at theme's loading time. * Prepares admin menus by setting an action for the implemented method '_adminMenus' if it exists. * * @uses do_action() Calls the 'ak_theme_loaded' action hook. * @param string $ID Theme internal short name (known as theme ID). * @return akTheme */ public function __construct ( $ID = '' ) { $this->style_file = STYLESHEETPATH . '/style.css'; $this->ID = ( empty($ID) ) ? strtolower(basename(TEMPLATEPATH)) : trim($ID) ; $this->loadThemeData(); $this->loadTranslations(); // We are installing the theme for the first time. if ( $this->installing ) { $this->installTheme(); } // Set the theme sidebars if ( function_exists('register_sidebars') && method_exists($this, 'registerSidebars') ) { $this->registerSidebars(); } // Configure some global theme options. $this->configureTheme(); // Load admin styles if ( is_admin() ) { add_action('admin_print_styles', array($this, '_adminStyles')); } // Init modules and widgets (Here we update the theme). add_action('init', array($this, '_themeInit')); add_action('widgets_init', array($this, '_widgetsInit')); // Add theme administration menus. if ( method_exists($this, '_adminMenus') ) { add_action('admin_menu', array($this, '_adminMenus')); // Add Panel menus. } // Startup the plugin. if ( method_exists($this, 'startUp') ) { $this->startUp(); } do_action('ak_theme_loaded'); } /** * Load theme translations. * Load the translation for main template and child theme (if exists). * * @return void */ final private function loadTranslations() { load_theme_textdomain('aktheme', TEMPLATEPATH . '/lang'); if ( TEMPLATEPATH !== STYLESHEETPATH && is_dir(STYLESHEETPATH . '/lang') ) { load_theme_textdomain('akchild', STYLESHEETPATH . '/lang'); } } /** * Configure the theme based on theme settings. * * @uses do_action() Calls the 'ak_theme_options_set' action hook. * @return void */ final private function configureTheme() { // Set metatags add_action('wp_head', array($this, '_metaTags') ); // Set the theme favicon if ( ! $this->getOption('disable-favicon') ) { add_action('wp_head', array($this, '_favicon')); add_action('admin_head', array($this, '_favicon')); } // Enable self ping. if ( ! $this->getOption('enable-selfping') ) { add_action('pre_ping', array($this, '_disableSelfPing')); } do_action('ak_theme_options_set'); } /** * Installs the theme. * Saves the theme version in DB, and calls the 'install' method. * * @uses do_action() Calls the 'ak_theme_installed' action hook. * @return void */ final private function installTheme () { // If there is an additional function to perform on installation. if ( method_exists($this, 'install') ) { $this->install(); } // Save options and version $this->cfg->saveOptions($this->ID); add_option($this->ID . '_version', $this->theme_data['Version']); do_action('ak_theme_installed'); } /** * Init the theme (In action 'plugins_loaded') * Here whe call the 'update' and 'init' functions. This is done after the plugins are loaded. * Also the theme version and settings are updated here. * * @uses do_action() Calls the 'ak_theme_updated' action hook. * @hook action 'init' * @access private * @return void */ final function _themeInit () { // Check if the module needs to be updated. if ( $this->needs_update ) { if ( method_exists($this, 'update') ) { $version = get_option($this->ID . '_version'); $this->update($version); } $this->cfg->saveOptions($this->ID); update_option($this->ID . '_version', $this->theme_data['Version']); do_action('ak_theme_updated'); } // Call the custom init for the theme when plugins are loaded. if ( method_exists($this, 'init') ) { $this->init(); } } /** * Inits the widgets (In action 'widgets_init') * In own themes standard sidebar always will be present (No check needed). * * @hook action 'widgets_init' * @access private * @return void */ final function _widgetsInit () { if ( method_exists($this, 'widgetsInit') ) { $this->widgetsInit(); } do_action('ak_theme_widgets_init'); } /** * Disables self pings. * This will disable sending pings to our own blog. * * @author Michael D. Adams * @link http://blogwaffe.com/2006/10/04/421/ * @version 0.2 * @hook action 'pre_ping' * @param array $links Link list of URLs to ping. */ final function _disableSelfPing( &$links ) { $home = get_option( 'home' ); foreach ( $links as $l => $link ) { if ( 0 === strpos( $link, $home ) ) { unset($links[$l]); } } } /** * Prepares and enqueues admin styles. * Uses the filter 'ak_theme_style_admin' for the admin style URL. * * @uses apply_filters() Calls the 'ak_theme_style_admin' on the style file URL. * @hook action 'admin_print_styles' * @access private * @return void */ final function _adminStyles () { $url = ''; if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists(STYLESHEETPATH . '/admin.css') ) { $url = get_stylesheet_directory_uri() . '/admin.css'; } elseif ( file_exists(TEMPLATEPATH . '/admin.css') ) { $url = get_template_directory_uri() . '/admin.css'; } $url = apply_filters('ak_theme_style_admin', $url); if ( ! empty($url) ) { wp_register_style($this->ID, $url, false, $this->theme_data['Version']); wp_enqueue_style($this->ID); } } /** * Returns a theme option. * If no specific option is requested, returns all options. * If requested a non existent settings, returns $default. * * @param $name Name for the option to return. * @param $default Default value to use if the option does not exists. * @return mixed The option's value or an array with all options. */ public function getOption ( $name = '', $default = false ) { return $this->cfg->getSetting($this->ID, $name, $default); } /** * Updates a theme option. * * @param string $name Option Name * @param mixed $value Option value * @return void */ public function updateOption ( $name, $value ) { $this->cfg->updateOption($this->ID, $name, $value ); } /** * Replaces ALL theme options by new ones. * * @param array $options Array with all options pairs (name=>value) * @return void */ public function setNewOptions ( $options ) { $this->cfg->replaceOptions($this->ID, $options); } /** * Returns theme data. * This data is loaded from the template style.css file. * * @see akTheme::$theme_data * @return mixed The parameter requested or an array wil all data. */ public function getThemeData ( $name = '' ) { if ( empty($name) ) { return $this->theme_data; } elseif ( isset( $this->theme_data[$name]) ) { return $this->theme_data[$name]; } else { return false; } } /** * Returns child theme data. * This data is loaded from the child style.css file. * * @see akTheme::$child_data * @return mixed The parameter requested or an array wil all data. */ public function getChildData ( $name = '' ) { if ( empty($name) ) { return $this->child_data; } elseif ( isset( $this->child_data[$name]) ) { return $this->child_data[$name]; } else { return false; } } /** * Checks if an option can be maneged on settings page. * Looks at the alkivia.ini file and if set there, the option will be disabled. * * @param string $option Option name. * @param boolean $show_notice Show a notice if disabled. * @return boolean If administration is allowed or not. */ public function allowAdmin( $option, $show_notice = true ) { if ( $this->cfg->isForced($this->ID, $option) ) { if ( $show_notice ) { echo '' . __('Option blocked by administrator.', 'aktheme') . ''; } return false; } else { return true; } } /** * Loads theme data and settings. * Data is loaded from style.css file headers. Settings from Database. * * @return void */ private function loadThemeData () { if ( empty($this->theme_data) ) { $this->theme_data = get_theme_data(TEMPLATEPATH . '/style.css'); } if ( TEMPLATEPATH !== STYLESHEETPATH && empty($this->child_data) ) { $this->child_data = get_theme_data($this->style_file); } $this->cfg = ak_settings_object(); if ( method_exists($this, 'defaults') ) { $this->cfg->setDefaults($this->ID, $this->defaults()); } $ver = get_option($this->ID . '_version'); if ( false === $ver ) { $this->installing = true; } elseif ( version_compare($ver, $this->theme_data['Version'], 'ne') ) { $this->needs_update = true; } } /** * Saves the current post state. * Used if we are looping a new query to reset previous state. * * @return void */ final protected function savePost() { global $post, $more; $this->saved['post'] = $post; $this->saved['more'] = $more; } /** * Restores the current post state. * Saved in savePost() * * @return void */ final protected function restorePost() { global $post, $more; $more = $this->saved['more']; $post = $this->saved['post']; if ( $post ) { setup_postdata($post); } } /** * Sets the favicon for the theme. * * @uses apply_filters() Calls apply_filters with the 'ak_theme_favicon' hook and the favicon url as content. * @hook actions 'wp_head' and 'admin_head' * @access private * @return void */ final function _favicon () { $file = '/images/favicon.ico'; $favicon = $this->getOption('favicon-url'); if ( false === $favicon ) { if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists(STYLESHEETPATH . $file) ) { $favicon = get_stylesheet_directory_uri() . $file; } elseif ( file_exists(TEMPLATEPATH . $file) ) { $favicon = get_template_directory_uri() . $file; } else { $favicon = ''; } } $favicon = apply_filters('ak_theme_favicon', $favicon); if ( ! empty($favicon) ) { echo '' . PHP_EOL; } } /** * Adds meta names for parent and child themes to head. * * @hook action 'wp_head' * @access private * @return void */ function _metaTags() { echo '' . PHP_EOL; if ( false !== $this->getChildData('Name') ) { echo '' . PHP_EOL; } } }