From f9344bf187422857e00892bfbfcd15bb7e7e0a44 Mon Sep 17 00:00:00 2001 From: Chris Scott <chris@iamzed.com> Date: Wed, 22 Sep 2010 11:32:40 -0400 Subject: [PATCH] add options page and use those settings. --- cloudfiles-cdn.php | 99 ++++++++++++++++---- voce-settings.php | 218 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 voce-settings.php diff --git a/cloudfiles-cdn.php b/cloudfiles-cdn.php index b91e41a..f357f94 100644 --- a/cloudfiles-cdn.php +++ b/cloudfiles-cdn.php @@ -10,9 +10,22 @@ Author URI: http://voceconnect.com/ class CloudfilesCdn { + var $submenu_general; + + var $option_group = 'cloudfiles_cdn'; + static $option_general = 'cloudfiles_cdn_general'; + function __construct() { - if (!defined('CF_USERNAME') || !defined('CF_API_KEY') || !defined('CF_CONTAINER') || !defined('CF_CONTAINER_URL')) { - // these should be defined in wp-config. if not, don't do anything here. + + // relies on Voce_Settings + if (!class_exists('Voce_Settings')) { + return; + } + + add_action('admin_menu', array($this, 'add_options_page')); + + if (!self::get_setting('username') || !self::get_setting('api_key') || !self::get_setting('container') || !self::get_setting('root_url')) { + // these are the minimum required settings. should add an admin notice later... return; } @@ -21,6 +34,57 @@ class CloudfilesCdn { add_filter('wp_generate_attachment_metadata', array('CloudfilesCdn', 'catch_wp_generate_attachment_metadata')); add_filter('bp_core_avatar_cropstore', array('CloudfilesCdn', 'catch_bp_core_avatar_cropstore')); add_action('bp_core_avatar_save', array('CloudfilesCdn', 'catch_bp_core_avatar_save'), 10, 2); + + } + + /** + * get general setting + * + * @param string $setting setting name + * @return mixed setting value or false if not set + */ + public static function get_setting($setting) { + $settings = get_option(self::$option_general); + return (isset($settings[$setting])) ? $settings[$setting] : false; + } + + /** + * adds the options page + * + * @return void + */ + public function add_options_page() { + $this->submenu_general = add_options_page('Cloudfiles CDN', 'Cloudfiles CDN', 'manage_options', self::$option_general, array(&$this, 'submenu_general')); + $settings = new Voce_Settings(self::$option_general, self::$option_general); + + $section = $settings->add_section('api', 'Cloudfiles API Settings', $this->submenu_general); + $section->add_field('username', 'Username', 'field_input'); + $section->add_field('api_key', 'API Key', 'field_input'); + $section->add_field('container', 'Container Name', 'field_input', array('description' => 'The container to store files in.')); + $section->add_field('root_url', 'Root URL', 'field_input', array('description' => 'The root URL to the container without a trailing slash.')); + $section->add_field('file_extensions', 'File Extensions', 'field_input'); + $section->add_field('enable_debug', 'Enable Debugging?', 'field_checkbox', array('description' => 'Enable error_log() to log upload/delete actions.')); + + } + + /** + * callback to display submenu_external + * + * @return void + */ + function submenu_general() { + ?> + <div class="wrap"> + <h2>Cloudfiles CDN Settings</h2> + <form method="post" action="options.php"> + <?php settings_fields(self::$option_general); ?> + <?php do_settings_sections($this->submenu_general); ?> + <p class="submit"> + <input name="Submit" type="submit" class="button-primary" value="<?php esc_attr_e('Save Changes'); ?>" /> + </p> + </form> + </div> + <?php } /** @@ -38,7 +102,7 @@ class CloudfilesCdn { $files[] = str_replace('-avatar2', '-avatar1', $files[0]); foreach ($files as $file) { - if (defined('CF_DEBUG_ENABLED') && CF_DEBUG_ENABLED) + if (self::get_setting('enable_debug')) error_log("DELETING OLD BP AVATAR: $file"); self::delete_file($file); @@ -56,7 +120,7 @@ class CloudfilesCdn { $relative_file_path = str_replace(ABSPATH, '', $file); $file_type = wp_check_filetype($file); - if (defined('CF_DEBUG_ENABLED') && CF_DEBUG_ENABLED) + if (self::get_setting('enable_debug')) error_log("UPLOADING BP AVATAR: $relative_file_path"); self::upload_file($file, $file_type['type'], $relative_file_path); } @@ -80,7 +144,7 @@ class CloudfilesCdn { $file = $size_data['file']; $relative_file_path = self::get_blog_path() . 'files' . trailingslashit($upload_dir['subdir']) . $file; $file_type = wp_check_filetype($file); - if (defined('CF_DEBUG_ENABLED') && CF_DEBUG_ENABLED) + if (self::get_setting('enable_debug')) error_log("UPLOADING INTERMEDIATE SIZE: $relative_file_path"); self::upload_file($upload_path . $file, $file_type['type'], $relative_file_path); } @@ -95,7 +159,7 @@ class CloudfilesCdn { * @return string filename */ private static function get_local_filename($url) { - return ABSPATH . str_replace(trailingslashit(CF_CONTAINER_URL), '', $url); + return ABSPATH . str_replace(trailingslashit(self::get_setting('root_url')), '', $url); } /** @@ -112,7 +176,7 @@ class CloudfilesCdn { $blog_path = self::get_blog_path(); $relative_url = $blog_path . self::remove_site_url($upload['url']); - if (defined('CF_DEBUG_ENABLED') && CF_DEBUG_ENABLED) + if (self::get_setting('enable_debug')) error_log("UPLOADING: $relative_url"); // upload file @@ -142,7 +206,7 @@ class CloudfilesCdn { $relative_path = self::get_blog_path() . 'files/' . $file; // delete the file from the CDN if it is on there - if (defined('CF_DEBUG_ENABLED') && CF_DEBUG_ENABLED) + if (self::get_setting('enable_debug')) error_log("DELETING FILE: $relative_path"); self::delete_file(str_replace(ABSPATH, '', $relative_path)); @@ -174,9 +238,9 @@ class CloudfilesCdn { * @return void */ private static function get_relative_file($file) { - $cont_url = CF_CONTAINER_URL; + $cont_url = self::get_setting('root_url'); if (strpos($file, $cont_url) !== false) { - if ($file_parts = explode(trailingslashit(CF_CONTAINER_URL), $file)) { + if ($file_parts = explode(trailingslashit(self::get_setting('root_url')), $file)) { // prepended w/bad upload path (e.g. http://c0002127.cdn1.cloudfiles.rackspacecloud.com/wp-content/uploads/2010/07/http://c0002127.cdn1.cloudfiles.rackspacecloud.com/wp-content/uploads/2010/07/653106995_338e53fb1416-150x150.jpg) if (isset($file_parts[2])) { return $file_parts[2]; @@ -198,7 +262,7 @@ class CloudfilesCdn { */ private static function delete_file($file) { require_once(trailingslashit(dirname(__FILE__)) . 'cloudfiles/cloudfiles.php'); - $auth = new CF_Authentication(CF_USERNAME, CF_API_KEY); + $auth = new CF_Authentication(self::get_setting('username'), self::get_setting('api_key')); try { $auth->authenticate(); @@ -208,7 +272,7 @@ class CloudfilesCdn { } $conn = new CF_Connection($auth); - $container = $conn->get_container(CF_CONTAINER); + $container = $conn->get_container(self::get_setting('container')); try { $obj = $container->get_object($file); @@ -231,7 +295,7 @@ class CloudfilesCdn { */ public static function cdn_attachment_url($url, $post_id) { if ($file = get_post_meta($post_id, '_wp_attached_file', true)) { - if (strpos($file, CF_CONTAINER_URL) !== false) { + if (strpos($file, self::get_setting('root_url')) !== false) { return $file; } } @@ -249,7 +313,7 @@ class CloudfilesCdn { */ private static function upload_file($file, $file_type, $file_url) { require_once(trailingslashit(dirname(__FILE__)) . 'cloudfiles/cloudfiles.php'); - $auth = new CF_Authentication(CF_USERNAME, CF_API_KEY); + $auth = new CF_Authentication(self::get_setting('username'), self::get_setting('api_key')); try { $auth->authenticate(); @@ -259,7 +323,7 @@ class CloudfilesCdn { } $conn = new CF_Connection($auth); - $container = $conn->get_container(CF_CONTAINER); + $container = $conn->get_container(self::get_setting('container')); $obj = $container->create_object($file_url); $obj->content_type = $file_type; @@ -271,7 +335,7 @@ class CloudfilesCdn { return false; } - if (defined('CF_DEBUG_ENABLED') && CF_DEBUG_ENABLED) + if (self::get_setting('enable_debug')) error_log("UPLOADED: $file, $file_type, $file_url"); return true; @@ -288,9 +352,10 @@ class CloudfilesCdn { } private static function remove_cdn_url($url) { - return str_replace(trailingslashit(CF_CONTAINER_URL), '', $url); + return str_replace(trailingslashit(self::get_setting('root_url')), '', $url); } } +require_once('voce-settings.php'); $cdn = new CloudfilesCdn(); \ No newline at end of file diff --git a/voce-settings.php b/voce-settings.php new file mode 100644 index 0000000..88f2de2 --- /dev/null +++ b/voce-settings.php @@ -0,0 +1,218 @@ +<?php +/* Copyright 2010 Chris Scott (cscott@voceconnect.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +if (!class_exists('Voce_Settings')) { + class Voce_Settings { + + private $page_name; + private $option_name; + private $page; + private $section; + + public function __construct($option_group, $option_name, $sanitize_callback = '') { + register_setting($option_group, $option_name, $sanitize_callback); + $this->option_name = $option_name; + } + + public function add_section($name, $title, $page, $callback = null) { + // use blank output to allow not setting a callback if no output is desired between heading and fields + $callback = (null === $callback) ? create_function('', 'echo \'\';') : $callback; + + add_settings_section($name, $title, $callback, $page); + $this->section = $name; + $this->page = $page; + return $this; + } + + public function add_field($id, $label, $type, $args = null, $page = null, $section = null) { + $section = (null === $section) ? $this->section : $section; + $page = (null === $page) ? $this->page : $page; + $this->add_settings_field( + $id, + $label, + $type, + $page, + $section, + $args + ); + } + + + /** + * helper to use the settings API to add a field + * + * @param string $id the HTML ID for the field + * @param string $label the label tag text + * @param string $display_callback the function to use for the field display + * @param string $extra_args extra args to pass to the callback + * @return void + */ + function add_settings_field($id, $label, $display_callback, $page, $section, $extra_args = null) { + + $args = array( + 'id' => $id, + 'label_for' => $id + ); + + if (is_array($extra_args)) { + $args += $extra_args; + } + + add_settings_field( + $id, + $label, + array(&$this, $display_callback), + $page, + $section, + $args + ); + } + + + /** + * checkbox callback for settings API + * + * @param string $args + * @return string checkbox + */ + function field_checkbox($args) { + $options = get_option($this->option_name); + + $defaults = array('prepend_field' => '', 'append_field' => '', 'class' => ''); + $args = wp_parse_args($args, $defaults); + extract($args); + + $description = ($description) ? sprintf('<p><span class="description">%s</span></p>', $description) : ''; + + $checked = checked($options[$id], '1', false); + + echo sprintf( + "%s<input id='%s' name='{$this->option_name}[%s]' type='checkbox' value='1' %s class='%s' />%s%s", + $prepend_field, + $id, + $id, + $checked, + $class, + $append_field, + $description + ); + } + + /** + * input type text callback for settings API + * + * @param string $args + * @return string input + */ + function field_input($args) { + $options = get_option($this->option_name); + + $defaults = array('prepend_field' => '', 'append_field' => '', 'class' => 'regular-text', 'type' => 'text'); + $args = wp_parse_args($args, $defaults); + extract($args); + + $description = (isset($description) && $description) ? sprintf('<p><span class="description">%s</span></p>', $description) : ''; + + if (!isset($value)) { + if (isset($options[$id])) { + $value = $options[$id]; + } else { + $value = ''; + } + } + + echo sprintf( + "%s<input id='%s' name='{$this->option_name}[%s]' type='%s' class='%s' value='%s' />%s%s", + $prepend_field, + $id, + $id, + $type, + $class, + esc_attr($value), + $append_field, + $description + ); + } + + /** + * textarea callback for settings API + * + * @param string $args + * @return string textarea + */ + function field_textarea($args) { + $options = get_option($this->option_name); + $id = $args['id']; + + $defaults = array('prepend_field' => '', 'append_field' => '', 'columns' => 40, 'rows' => 8, 'class' => 'large-text'); + $args = wp_parse_args($args, $defaults); + extract($args); + + $description = (isset($description) && $description) ? sprintf('<p><span class="description">%s</span></p>', $description) : ''; + + echo sprintf( + "%s<textarea id='%s' name='{$this->option_name}[%s]' columns='%s' rows='%s' class='%s' />%s</textarea>%s%s", + $prepend_field, + $id, + $id, + $columns, + $rows, + $class, + esc_attr($options[$id]), + $append_field, + $description + ); + } + + function field_radio($args) { + $options = get_option($this->option_name); + $id = $args['id']; + + $defaults = array('type' => 'radio', 'class' => ''); + $args = wp_parse_args($args, $defaults); + extract($args); + + if (!$items) { + return; + } + + echo '<fieldset><p>'; + foreach ($items as $item) { + if (!empty($options[$id])) { + $checked = checked($options[$id], $item['value'], false); + } else { + $checked = false; + } + + echo sprintf( + "<label> <input id='%s' name='{$this->option_name}[%s]' type='%s', class='%s' value='%s' %s /> %s</label><br />", + $id, + $id, + $type, + $class, + esc_attr($item['value']), + $checked, + esc_html($item['text']) + ); + } + echo '</fieldset></p>'; + + $description = (isset($description) && $description) ? sprintf('<p><span class="description">%s</span></p>', $description) : ''; + echo $description; + } + } +} \ No newline at end of file -- GitLab