Index: trunk/in-portal.php =================================================================== diff -u --- trunk/in-portal.php (revision 0) +++ trunk/in-portal.php (revision 16336) @@ -0,0 +1,308 @@ +In-Portal CMS website templates as building blocks inside WordPress theme. + * Version: 1.0.0 + * Author: Intechnic + * Author URI: http://www.intechnic.com + * License: GNU/GPL + */ +defined('ABSPATH') or die('Plugin file cannot be accessed directly.'); + +class InPortal +{ + + protected $optionDefaults = array( + 'inportal_website_url' => '', + 'inportal_cache_duration' => '60', + ); + + /** + * Performs plugin initialization. + */ + public function __construct() + { + if ( is_admin() ) { + add_action('admin_menu', array($this, 'hookAdminMenu')); + add_action('admin_init', array($this, 'hookAdminInit')); + } + } + + /** + * Additional actions upon plugin activation (installation/upgrade). + * + * @return void + */ + public function hookActivation() + { + global $wpdb; + + foreach ( $this->optionDefaults as $option => $default ) { + add_option($option, $default); + } + + $sql = 'CREATE TABLE ' . $this->getTableName() . ' ( + Id int(11) NOT NULL AUTO_INCREMENT, + TemplateName varchar(255) NOT NULL DEFAULT "", + TemplateContent text, + ExpiresOn int(11) DEFAULT NULL, + PRIMARY KEY (Id), + UNIQUE KEY TemplateName (TemplateName(50)) + ) ' . $wpdb->get_charset_collate(); + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + dbDelta($sql); + } + + /** + * Returns database table used for template content caching. + * + * @return string + */ + protected function getTableName() + { + global $wpdb; + + return $wpdb->prefix . 'inp_template_cache'; + } + + /** + * Additional actions upon plugin deactivation. + * + * @return void + */ + public function hookDeactivation() + { + + } + + /** + * Additional actions upon plugin removal. + * + * @return void + */ + public function hookUninstall() + { + foreach ( array_keys($this->optionDefaults) as $option ) { + delete_option($option); + } + } + + /** + * Adds plugin configuration page. + * + * @return void + */ + public function hookAdminMenu() { + add_options_page( + __('In-Portal CMS Settings', 'in-portal'), + __('In-Portal CMS', 'in-portal'), + 'administrator', + 'in-portal-settings', + array($this, 'hookMenuPage') + ); + } + + /** + * Displays contents of plugin configuration page. + * + * @return void + */ + public function hookMenuPage() + { + ?> +
+

+ +
+ + + + + + + + + + + +
+ +

+ +

+
+ +

+ +

+
+ + +
+
+ optionDefaults) as $option ) { + register_setting('in-portal-settings-group', $option); + add_filter('sanitize_option_' . $option, array($this, 'hookSanitizeOption'), 10, 2); + } + } + + /** + * Performs option value sanitization. + * + * @param mixed $value Option value. + * @param string $option Option name. + * + * @return mixed + */ + public function hookSanitizeOption($value, $option) + { + $error = ''; + + switch ( $option ) { + case 'inportal_website_url': + if ( !strlen($value) ) { + $error = __('The In-Portal CMS Address is required.'); + } + elseif ( filter_var($value, FILTER_VALIDATE_URL) === false ) { + $error = __('The In-Portal CMS Address you entered did not appear to be a valid URL. Please enter a valid URL.'); + } + else { + $value = rtrim(preg_replace('/index.php$/', '', $value), '/') . '/'; + } + break; + + case 'inportal_cache_duration': + if ( !strlen($value) ) { + $error = __('The Cache Duration is required.'); + } + elseif ( !preg_match('/^[\d]+$/', $value) ) { + $error = __('The Cache Duration must be a positive number. Enter "0" do disable caching.'); + } + break; + } + + if ( $error ) { + add_settings_error($option, 'invalid_' . $option, $error); + + // Don't save invalid value. + return get_option($option, $this->optionDefaults[$option]); + } + + return $value; + } + + /** + * Theme tag: returns contents of In-Portal CMS template. + * + * @param string $name Template name. + * @param array $params Template parameters. + * @param string|null $cache_duration Cache duration. + * + * @return string|WP_Error + */ + public function getTemplate($name, array $params = array(), $cache_duration = null) + { + global $wpdb; + + $table_name = $this->getTableName(); + + $sql = 'SELECT * + FROM ' . $table_name . ' + WHERE TemplateName = %s'; + $cached_data = $wpdb->get_row($wpdb->prepare($sql, $name)); + + $now = time(); + + if ( is_object($cached_data) && $cached_data->ExpiresOn > $now ) { + return $this->applyTemplateParams($cached_data->TemplateContent); + } + + $base_url = get_option('inportal_website_url'); + + if ( !$base_url ) { + return new WP_Error('missing_url', __('The In-Portal CMS Address is not specified.')); + } + + $params['t'] = $name; // The name of In-Portal CMS template. + $params['is_wordpress'] = 1; // Marker to allow returning WordPress-specific HTML. + + $response = wp_remote_get($base_url . '?' . http_build_query($params)); + + if ( $response['response']['code'] !== 200 ) { + return new WP_Error('missing_template', __('The In-Portal CMS template "' . $name . '" not found.')); + } + + $content = wp_remote_retrieve_body($response); + + if ( !isset($cache_duration) ) { + $cache_duration = get_option('inportal_cache_duration'); + } + + $wpdb->replace( + $table_name, + array( + 'TemplateName' => $name, + 'TemplateContent' => $content, + 'ExpiresOn' => strtotime('+' . $cache_duration . ' minutes'), + ) + ); + + return $this->applyTemplateParams($content); + } + + /** + * Replaces template parameters in HTML comments within template HTML. + * + * @param string $template_content Template content. + * @param array $params Template params. + * + * @return string + */ + protected function applyTemplateParams($template_content, array $params = array()) + { + foreach ( $params as $key => $value ) { + $template_content = str_replace('', $value, $template_content); + } + + return $template_content; + } +} + + +/** + * Theme tag: returns contents of In-Portal CMS template. + * + * @param string $name Template name. + * @param array $params Template parameters. + * @param string|null $cache_duration Cache duration. + * + * @return string|WP_Error + */ +function inportal_get_template($name, $params = array(), $cache_duration = null) +{ + global $in_portal; + + return $in_portal->getTemplate($name, $params, $cache_duration); +} + +$in_portal = new InPortal(); + +// These type of hooks needs to be registered in main file (not in class constructor). +register_activation_hook(__FILE__, array($in_portal, 'hookActivation')); +register_deactivation_hook(__FILE__, array($in_portal, 'hookDeactivation')); +register_uninstall_hook(__FILE__, array($in_portal, 'hookUninstall'));