_a('-- None --'),
'cover' => _a('Cover'),
'uncover' => _a('Uncover'),
'curtainX' => _a('Curtain X'),
'curtainY' => _a('Curtain Y'),
'fade' => _a('Fade'),
'scrollUp' => _a('Scroll Up'),
'scrollDown' => _a('Scroll Down'),
'scrollLeft' => _a('Scroll Left'),
'scrollRight' => _a('Scroll Right'),
'scrollUp, scrollDown, scrollLeft, scrollRight' => _a('Scroll Random'),
'shuffle' => _a('Shuffle'),
'toss' => _a('Toss'),
'wipe' => _a('Wipe'),
))));
// easing equations used by effects
define("EASING", serialize(apply_filters('atom_easing', array(
'easeOutCirc' => _a('Circular'),
'easeOutElastic' => _a('Elastic'),
'easeOutBack' => _a('Back'),
'easeOutBounce' => _a('Bounce'),
'easeOutExpo' => _a('Exponential'),
'easeOutQuad' => _a('Quadratic'),
'easeOutQuart' => _a('Quartic'),
'easeOutQuint' => _a('Quintic'),
))));
// if the current wp version is lower than the minimum required version display a error message and don't go further
if (WP_VERSION < WP_REQ_VERSION):
add_action('admin_notices', 'atom_unsupported_wp_version');
add_action('wp', 'atom_unsupported_wp_version');
// if everything is ok, set up the theme
else:
// set up administration pages
if(is_admin()) require("admin/interface.php");
if(!defined('ATOM_RESET')) require(TEMPLATEPATH.'/core/defaults.php');
// check for expired transients and remove them if needed
add_action('wp_scheduled_delete', 'atom_delete_expired_transients');
// setup up localization, menus and theme settings
add_action('after_setup_theme', 'atom_setup');
// set up thumbnail sizes (must run before ajax)
add_action('init', 'atom_set_thumb_sizes');
// ajax/get requests
add_action('init', 'atom_requests', 11);
// inline css (layout settings)
add_action('wp_head', 'atom_inline_css', 420);
// register js and css
add_action('wp', 'atom_enqueue_scripts');
add_action('wp', 'atom_enqueue_styles');
// load js and css
add_action('wp_print_scripts', 'atom_print_scripts');
add_action('wp_print_styles', 'atom_print_styles');
// set up advertisment blocks
if(!is_admin()) add_action('wp', 'atom_setup_ads');
// generator meta
add_filter('get_the_generator_xhtml', 'atom_meta_generator', 10, 2);
// remove theme settings on theme change?
if(atom_get_options('remove_settings')) add_action('switch_theme', 'atom_remove_options');
// footer hook
add_action('wp_footer', 'atom_footer', 99);
/*/ gzipped output
if(atom_get_options('optimize') && !defined('DOING_AJAX') && extension_loaded("zlib") && (ini_get("output_handler") != "ob_gzhandler"))
// && substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && stripos($_SERVER['REQUEST_URI'], 'wp-includes/js/tinymce') === false
add_action('get_header', create_function('', '@ob_end_clean();@ini_set("zlib.output_compression", 1);')); // before output starts
//*/
// css class adjustments
add_filter('wp_nav_menu_args', 'atom_nav_menu_settings');
add_filter('page_css_class', 'atom_page_css_classes', 10, 2);
add_filter('nav_menu_css_class', 'atom_menu_css_classes', 10, 2);
add_filter('body_class', 'atom_body_class');
add_filter('post_class', 'atom_post_class');
add_filter('comment_class', 'atom_comment_class');
// search taxonomies
add_filter('posts_where','atom_search_where');
add_filter('posts_join', 'atom_search_join');
add_filter('posts_groupby', 'atom_search_groupby');
if(atom_get_options('debug'))
add_action('wp_footer', 'atom_debug_info');
// wp admin bar (3.1+)
if(WP_VERSION >= 3.1) add_action('admin_bar_menu', 'atom_wp_admin_bar_menu', 79);
// user functions
if(!is_admin()) atom_user_functions();
atom("core");
return true;
endif;
return false;
}
/**
* Run a function linked to a specific tag
* Same as do_action(), just prepends the ATOM_ prefix to the tag
*
* @since 1.2
*
* @param string $tag tag name
* @param string $args arguments
*/
function atom($tag = '', $args = ''){
if (!$tag) return false;
do_action("atom_{$tag}", $args);
}
/**
* Replaces add_filter and add_action (same behaviour, just prepends the ATOM_ prefix to the tag)
*
* @since 1.2
*
* @param string $tag tag name
* @param string $function_to_add function name
* @param string $priority priority
* @param string $accepted_args # of arguments accepted
*
* @return mixed Filtered value
*/
function atom_add($tag, $function_to_add, $priority = 10, $accepted_args = 1){
if (!$tag) return false;
return add_filter("atom_{$tag}", $function_to_add, $priority, $accepted_args);
}
/**
* Get a list of available layouts
*
* @since 1.3
*/
function atom_available_layout_types(){
return array(
'col-1',
'col-2-left',
'col-2-right',
'col-3',
'col-3-left',
'col-3-right',
);
}
/**
* Set up the theme and attach the core actions and filter hooks
*
* @since 1.0
*/
function atom_setup(){
// editor-style.css
add_editor_style();
// post thumbnails
add_theme_support('post-thumbnails');
/*/ post formats, wp 3.1+ -- @todo!
add_theme_support('post-formats', array('aside', 'gallery'));
//*/
// posts & comments RSS feed links
add_theme_support('automatic-feed-links');
// localize the theme
load_theme_textdomain(ATOM, TEMPLATEPATH.'/lang');
$locale = get_locale();
$locale_file = TEMPLATEPATH."/lang/{$locale}.php";
if (is_readable($locale_file)) require_once($locale_file);
// nav menus
register_nav_menus(atom_nav_menus());
// synchronize theme settings
atom_verify_options();
// adjust content width variable, probably useless...
if (!isset($GLOBALS['content_width']) && atom_get_options('page_width') == 'fixed'):
$primary = explode(";", atom_get_options('dimensions_fixed_'.atom_get_options('layout')));
$primary = empty($primary[0]) ? 960 : intval($primary[0]);
$GLOBALS['content_width'] = ($primary - 20);
endif;
}
/**
* Set up post thumbnail sizes
*
* @since 1.0
*/
function atom_set_thumb_sizes(){
$size = (atom_get_options('post_thumb_size') == 'media') ? array(atom_get_options('thumbnail_size_w'), atom_get_options('thumbnail_size_h')) : explode('x', atom_get_options('post_thumb_size'));
set_post_thumbnail_size(intval($size[0]), intval($size[1]), true); // same as add_image_size('post-thumbnail' ...);
add_image_size('featured-thumbnail', 164, 164, true);
add_image_size('gallery', 940, 240, true);
//add_image_size('related-post-thumbnail', 100, 100, true);
atom("set_thumb_sizes");
}
/**
* Displays a error message telling the user that he needs to upgrade his Worpdress installation
*
* @since 1.0
*/
function atom_unsupported_wp_version(){
if(current_user_can('edit_theme_options'))
$message = sprintf(_a('Your site is running on %1$s. %2$s requires at least %3$s.'), 'WordPress '.WP_VERSION, THEME_NAME, 'WordPress '.WP_REQ_VERSION.'');
else $message = sprintf(_a("The site is temporarily down for maintainance. Come back in a few minutes, or login in here if you're de site admin"), ' href="'.get_admin_url().'"');
if(current_user_can('edit_theme_options') && !is_admin()) $message .= ' '.sprintf(_a("Go to your %s"), ''._a("Dashboard").'');
if(!is_admin()) wp_die($message); else echo "
{$message}
";
}
/**
* Check if we're in theme preview mode (Atom > Design)
*
* @since 1.0
*
* @return bool True or False
*/
function atom_preview_mode(){
if(isset($_GET['themepreview']) && current_user_can('edit_theme_options')) return true;
return false;
}
/**
* Get the current page URL
*
* @since 1.0
*
* @return string the page URL.
*/
function atom_get_current_page_url() {
$request = esc_url($_SERVER["REQUEST_URI"]);
// wp-themes fake request url fix :)
if (strpos($_SERVER["SERVER_NAME"], 'wp-themes.com') !== false) $request = str_replace($request, '/wordpress/', '/');
// ssl?
$pageURL = (is_ssl() ? 'https' : 'http').'://';
if ($_SERVER["SERVER_PORT"] != "80") $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$request; else $pageURL .= $_SERVER["SERVER_NAME"].$request;
// check if the site uses "www" or not
if (false === strpos(atom_get_options('home'), '://www.')) $pageURL = str_replace('://www.', '://', $pageURL);
if (false !== strpos(atom_get_options('home'), '://www.') && false === strpos($pageURL, '://www.')) $pageURL = str_replace('://', '://www.', $pageURL);
return $pageURL;
}
/**
* Sort a multi-dimensional array by one of its subvalues
* from http://firsttube.com/read/sorting-a-multi-dimensional-array-with-php/
* -- not used anymore (was being used before 1.2.7 to sort entries in the authors widget)
*
* @since 1.0
*
* @param array $a The Array
* @param string $subkey The Value
* @param string $order Sort order, ASC by defalt.
* @return array The sorted Array
*/
function atom_sort_array_by_subkey($a, $subkey, $order = 'ASC') {
foreach($a as $k => $v) $b[$k] = strtolower($v[$subkey]);
if($order != 'ASC') arsort($b); else asort($b);
foreach($b as $key => $val) $c[] = $a[$key];
return $c;
}
/**
* Output the favicon meta
*
* @since 1.0
*/
function atom_favicon(){
if($favicon = atom_get_options('favicon')) echo "\n";
}
/**
* Register javascript files used by ATOM
*
* @since 1.3
*/
function atom_enqueue_scripts(){
// enqueue jquery & related scripts
if(is_admin()) return;
if(atom_get_options('jquery')):
// unregister wp's jquery
wp_deregister_script('jquery');
// load google's jquery, should be faster theoretically
wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"), false, '1.4.3');
// jquery
wp_enqueue_script('jquery');
// jquery plugins
wp_enqueue_script(ATOM, THEME_URL.'/js/jquery.atom.js'.(atom_get_options('optimize') ? '.php' : NULL), array('jquery'), THEME_VERSION, true);
// post-message
if(atom_preview_mode())
wp_enqueue_script('post-message', THEME_URL.'/core/admin/pm.js', array('jquery'), THEME_VERSION, true);
// jquery init function
if(atom_get_options('jquery_init_query'))
wp_enqueue_script(ATOM.'-init', esc_url_raw(add_query_arg('jquery_init', 1, (is_404() ? home_url() : atom_get_current_page_url()))), array('jquery', ATOM), THEME_VERSION, true);
endif;
atom("js");
}
/**
* Load jQuery & related .js
* (using head.js if "optimize" is checked)
*
* @since 1.3
*
* @todo load locales in order (eg. one of the js files from the Symposium plugin requires a locale loaded before it)
*/
function atom_print_scripts(){
global $wp_scripts, $concatenate_scripts;
if(is_admin() || !is_a($wp_scripts, 'WP_Scripts') || !atom_get_options('optimize') || atom_preview_mode()) return;
$scripts = $locales = array();
$queue = $wp_scripts->queue;
$wp_scripts->all_deps($queue); // arrange the list of scripts based on dependencies
foreach($wp_scripts->to_do as $key => $handle):
if ($wp_scripts->registered[$handle]->ver === null) $ver = '';
else $ver = $wp_scripts->registered[$handle]->ver ? $wp_scripts->registered[$handle]->ver : $wp_scripts->default_version;
if (isset($wp_scripts->args[$handle]))
$ver = $ver ? $ver.'&'. $wp_scripts->args[$handle] : $wp_scripts->args[$handle];
$src = $wp_scripts->registered[$handle]->src;
if($locale = $wp_scripts->print_scripts_l10n($handle, false)) $locales[] = $locale;
if(!preg_match('|^https?://|', $src) && ! ($wp_scripts->content_url && 0 === strpos($src, $wp_scripts->content_url))) $src = $wp_scripts->base_url.$src;
if(!empty($ver)) $src = add_query_arg('ver', $ver, $src);
$src = esc_url(apply_filters('script_loader_src', $src, $handle));
$scripts[$handle] = $src;
unset($wp_scripts->to_do[$key]);
$wp_scripts->done[] = $handle;
endforeach;
if (empty($scripts)) return;
echo "\n";
echo "\n";
$wp_scripts->reset();
return $wp_scripts->done;
}
/**
* Register CSS files used by ATOM
*
* @since 1.3
*/
function atom_enqueue_styles(){
if(is_admin()) return;
global $post;
if(is_child_theme())
wp_enqueue_style(ATOM, get_stylesheet_uri(), array(), THEME_VERSION);
if(atom_is_option_enabled('color_scheme')):
// color/design scheme (adde custom field for testing)
if (is_single() || is_page()) $style = get_post_meta($post->ID, 'style', true);
// if no c.f. use the theem setting
if(!isset($style) || !$style) $style = atom_get_options('color_scheme');
if (!empty($style)):
wp_enqueue_style(ATOM.'-core', THEME_URL.'/style.css', array(), THEME_VERSION);
wp_enqueue_style(ATOM.'-style', THEME_STYLES_URL.'/'.$style, array(ATOM.'-core'), THEME_VERSION);
endif;
endif;
// country flags css
if(defined('COUNTRY_FLAGS') || ((is_single() || is_page()) && atom_get_options('comment_flags')))
wp_enqueue_style(ATOM."-flags", THEME_URL.'/core/ip2c/flags.css', array(ATOM), THEME_VERSION);
/*/ print styles -- removed
wp_enqueue_style(ATOM."-print", THEME_URL.'/print.css', array(ATOM), THEME_VERSION, 'print');
//*/
}
/**
* Load stylesheets.
* Will compress and concatenate them all into a single file if "optimize" is checked.
* Based on "JS & CSS Script Optimizer" by evgenniy - http://4coder.info/en/
*
* @since 1.3
*
* @todo test rtl
*/
function atom_print_styles(){
global $wp_styles, $concatenate_scripts;
if(is_admin() || !is_a($wp_styles, 'WP_Styles') || !atom_get_options('optimize') || atom_preview_mode()) return;
$styles = array();
$queue = $wp_styles->queue;
$wp_styles->all_deps($queue);
$queue_unset = array();
$home = site_url('/');
foreach($wp_styles->to_do as $key => $handle):
if($wp_styles->registered[$handle]->ver === null) $ver = '';
else $ver = $wp_styles->registered[$handle]->ver ? $wp_styles->registered[$handle]->ver : $wp_styles->default_version;
if(isset($wp_styles->args[$handle]))
$ver = $ver ? $ver.'&'.$wp_styles->args[$handle] : $wp_styles->args[$handle];
if(isset($wp_styles->registered[$handle]->args)) $media = esc_attr($wp_styles->registered[$handle]->args); else $media = 'all';
$href = $wp_styles->_css_href($wp_styles->registered[$handle]->src, $ver, $handle);
// rtl?
if('rtl' === $wp_styles->text_direction && isset($wp_styles->registered[$handle]->extra['rtl']) && $wp_styles->registered[$handle]->extra['rtl'])
if(is_bool( $wp_styles->registered[$handle]->extra['rtl'])):
$suffix = isset($wp_styles->registered[$handle]->extra['suffix']) ? $wp_styles->registered[$handle]->extra['suffix'] : '';
$href = str_replace("{$suffix}.css", "-rtl{$suffix}.css", $wp_styles->_css_href($wp_styles->registered[$handle]->src , $ver, "$handle-rtl"));
else:
$href = $wp_styles->_css_href($wp_styles->registered[$handle]->extra['rtl'], $ver, "$handle-rtl");
endif;
// ignore external styles
$external = false;
if((strpos($href, 'http', 0) !== false) && (strpos($href, $home, 0) === false)) $external = true;
if($external) continue;
$styles[$media][$handle] = $href;
endforeach;
if (false === ($cache = get_transient('atom_css_cache'))) $cache = array();
// paths
$upload_path = is_multisite() ? get_site_option('upload_path') : get_option('upload_path');
$upload_url = get_option('upload_url_path');
$upload_path = $upload_path ? trailingslashit($upload_path) : ABSPATH.'wp-content/uploads/';
$upload_url = $upload_url ? trailingslashit($upload_url) : site_url('/wp-content/uploads/');
foreach($styles as $media => $items):
$handles = array_keys($items);
$handles = implode(', ', $handles);
$cache_name = md5($handles);
$cache_file_path = "{$upload_path}{$cache_name}.css";
$cache_file_url = "{$upload_url}{$cache_name}.css";
// calculate modified tag
$hash = 0;
foreach($items as $handle => $style):
$parts = parse_url($style);
$file_path = str_replace(site_url('/'), ABSPATH, $parts['scheme'].'://'.$parts['host'].$parts['path']);
$hash += @filemtime($file_path);
endforeach;
if(($cache[$media][$cache_name] != $hash) || !is_readable($cache_file_path)): // build cache
$css = '';
foreach($items as $handle => $style):
$css .= "/* $handle: ($style) */\n";
$content = @file_get_contents($style);
$content = atom_compress_css($content, $style);
$css .= "{$content}\n";
endforeach;
$comment = "/*\nCache: {$handles}\n*/\n";
// save file
$saved = false;
if(is_writable($upload_path)):
$fhandle = @fopen($cache_file_path, 'w+');
if($fhandle):
@fwrite($fhandle, $comment.$css, strlen($comment.$css));
$saved = true;
atom_add_debug_message("Stylesheet cache rebuilt ({$cache_file_url}).");
endif;
endif;
if($saved):
$cache[$media][$cache_name] = $hash;
set_transient('atom_css_cache', $cache, 60*60*24); // 1 day cache
else:
atom_add_debug_message("Failed to create stylesheet cache ({$cache_file_url}).", 1);
return false;
endif;
endif;
echo "\n\n";
endforeach;
foreach ($wp_styles->to_do as $key => $handle):
unset($wp_styles->to_do[$key]);
$wp_styles->done[] = $handle;
endforeach;
}
/**
* Remove comments, tabs, spaces, newlines, etc. from a CSS file.
* Based on "JS & CSS Script Optimizer" by evgenniy - http://4coder.info/en/
*
* @since 1.3
*
* @param string $css CSS styles
* @param string $path path to replace url() with
*/
function atom_compress_css($css, $path) {
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
$css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $css);
// url
$dir = dirname($path).'/';
$css = preg_replace('|url\(\'?"?([a-zA-Z0-9\-_\s\./]*)\'?"?\)|', "url(\"$dir$1\")", $css);
return $css;
}
/**
* Inline styles (layout settings)
*
* @since 1.3
*
* @global $post object
*/
function atom_inline_css(){
global $post;
// get the theme settings
$s = atom_get_options();
$css = '';
if(atom_is_option_enabled('layout')):
$s['layout'] = atom_get_layout_type();
// column dimensions
$w = $s['page_width'];
$unit = ($w == 'fluid') ? '%' : 'px';
$gs = ($w == 'fluid') ? '100' : '960';
switch ($s['layout']):
case 'col-2-left':
$sb = explode(";", $s["dimensions_{$w}_col-2-left"]);
$css .= 'body.'.$w.'.col-2-left #primary-content{width:'.($gs-$sb[0]).$unit.';left:'.($gs).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-2-left #sidebar{width:'.$sb[0].$unit.';left:0}'.PHP_EOL;
$css .= 'body.'.$w.'.col-2-left #mask-1{right:'.($gs-$sb[0]).$unit.'}'.PHP_EOL;
break;
case 'col-2-right':
$sb = explode(";", $s["dimensions_{$w}_col-2-right"]);
$css .= 'body.'.$w.'.col-2-right #primary-content{width:'.($gs-($gs-$sb[0])).$unit.';left:'.($gs-$sb[0]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-2-right #sidebar{width:'.($gs-$sb[0]).$unit.';left:'.($gs-$sb[0]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-2-right #mask-1{right:'.($gs-$sb[0]).$unit.'}'.PHP_EOL;
break;
case 'col-3':
$sb = explode(";", $s["dimensions_{$w}_col-3"]);
$css .= 'body.'.$w.'.col-3 #primary-content{width:'.($gs-$sb[0]-($gs-$sb[1])).$unit.';left:'.$gs.$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3 #sidebar{width:'.$sb[0].$unit.';left:'.($gs-$sb[1]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3 #sidebar2{width:'.($gs-$sb[1]).$unit.';left:'.($gs-$sb[0]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3 #mask-2{right:'.($gs-$sb[1]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3 #mask-1{right:'.($gs-$sb[0]-($gs-$sb[1])).$unit.'}'.PHP_EOL;
break;
case 'col-3-left':
$sb = explode(";", $s["dimensions_{$w}_col-3-left"]);
$css .= 'body.'.$w.'.col-3-left #primary-content{width:'.($gs-$sb[1]).$unit.';left:'.($gs+($sb[1]-$sb[0])).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3-left #sidebar{width:'.$sb[0].$unit.';left:'.($sb[1]-$sb[0]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3-left #sidebar2{width:'.($sb[1]-$sb[0]).$unit.';left:'.($sb[1]-$sb[0]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3-left #mask-2{right:'.($gs-$sb[1]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3-left #mask-1{right:'.($sb[1]-$sb[0]).$unit.'}'.PHP_EOL;
break;
case 'col-3-right':
$sb = explode(";", $s["dimensions_{$w}_col-3-right"]);
$css .= 'body.'.$w.'.col-3-right #primary-content{width:'.$sb[0].$unit.';left:'.(($gs-$sb[0]-($gs-$sb[1]))+($gs-$sb[1])).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3-right #sidebar{width:'.($gs-$sb[0]-($gs-$sb[1])).$unit.';left:'.($gs-$sb[0]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3-right #sidebar2{width:'.($gs-$sb[1]).$unit.';left:'.($gs-$sb[0]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3-right #mask-2{right:'.($gs-$sb[1]).$unit.'}'.PHP_EOL;
$css .= 'body.'.$w.'.col-3-right #mask-1{right:'.($sb[1]-$sb[0]).$unit.'}'.PHP_EOL;
break;
endswitch;
// page width
if(($s['page_width'] == 'fluid'))
$css .= ".page-content{max-width:{$s['page_width_max']}px;}\n";
endif;
// background image
if(atom_is_option_enabled('background_image') && $s['background_image'])
$css .= $s['background_image_selector'].'{background-image:url("'.$s['background_image'].'");}'.PHP_EOL;
// background color
if(atom_is_option_enabled('background_color') && ($s['background_color']) && ($s['background_color'] != '000000'))
$css .= $s['background_color_selector'].'{background-color:#'.$s['background_color'].';}'.PHP_EOL;
// extra css may be added by plugins etc.
atom("inline_css");
// user css (use template system)
if($s['css']) $css .= atom_render_template($s['css'], array(
'CHILD_THEME_URL' => CHILD_THEME_URL,
'THEME_URL' => THEME_URL,
'THEME_STYLES_URL' => THEME_STYLES_URL,
'BLOG_URL' => BLOG_URL,
));
// search for CSS custom field
if (is_single() || is_page()):
$meta_css = get_post_meta($post->ID, 'css', true);
if (!empty($meta_css)) $css .= atom_render_template($s['css'], array(
'CHILD_THEME_URL' => CHILD_THEME_URL,
'THEME_URL' => THEME_URL,
'THEME_STYLES_URL' => THEME_STYLES_URL,
'BLOG_URL' => BLOG_URL,
));
endif;
if(!empty($css)) echo "\n";
}
/**
* wp_footer hook
*
* @since 1.0
*/
function atom_footer(){
if(!atom_get_options('jquery_init_query') && atom_get_options('jquery')): ?>
ID, 'redirect', true)) wp_redirect(esc_url($url), 301); // @todo: add redirect type cf.
endif;
}
/**
* Advertisment blocks
*
* @since 1.3
*/
class AtomAds{
var $atom_active_ads = array();
function AtomAds($ads){
global $current_user, $post;
foreach($ads as $ad):
$data = array();
$active = false;
parse_str($ad['atts'], &$data);
$data['n'] = empty($data['n']) ? 1 : min(max(intval($data['n']), 1), atom_get_options('posts_per_page'));
// page
$active = call_user_func("is_{$data['page']}");
// user: all/visitor
if(is_numeric($data['to'])) $active = !$active || ($active && $data['to'] && is_user_logged_in()) ? false : $active;
// user: role
else $active = $active && in_array($data['to'], $current_user->roles);
// comment status, on single pages
if($data['when'] && is_single()) $active = $active && ($data['when'] == $post->comment_status);
$data['html'] = $ad['html'];
if($active) $this->atom_active_ads[$data['place']][] = $data;
endforeach;
foreach($this->atom_active_ads as $place => $data) atom_add($place, array(&$this, $place));
}
function before_main_content(){
if(isset($this->atom_active_ads['before_main_content']))
foreach($this->atom_active_ads['before_main_content'] as $key => $ad):
echo $ad['html'];
unset($this->atom_active_ads['before_main_content'][$key]);
endforeach;
}
function before_primary(){
if(isset($this->atom_active_ads['before_primary']))
foreach($this->atom_active_ads['before_primary'] as $key => $ad):
echo $ad['html'];
unset($this->atom_active_ads['before_primary'][$key]);
endforeach;
}
function after_primary(){
if(isset($this->atom_active_ads['after_primary']))
foreach($this->atom_active_ads['after_primary'] as $key => $ad):
echo $ad['html'];
unset($this->atom_active_ads['after_primary'][$key]);
endforeach;
}
function after_post(){
global $wp_query;
if(isset($this->atom_active_ads['after_post']))
foreach($this->atom_active_ads['after_post'] as $key => $ad)
if($ad['n'] == ($wp_query->current_post) + 1):
echo $ad['html'];
unset($this->atom_active_ads['after_post'][$key]);
endif;
}
function before_post(){
global $wp_query;
if(isset($this->atom_active_ads['before_post']))
foreach($this->atom_active_ads['before_post'] as $key => $ad)
if($ad['n'] == ($wp_query->current_post) + 1):
echo $ad['html'];
unset($this->atom_active_ads['before_post'][$key]);
endif;
}
function before_comment(){
global $__comment_count;
if(isset($this->atom_active_ads['before_comment']))
foreach($this->atom_active_ads['before_comment'] as $key => $ad)
if($ad['n'] == $__comment_count):
echo $ad['html'];
unset($this->atom_active_ads['before_comment'][$key]);
endif;
}
}
/**
* Set up the theme settings
* This should only run once (after the theme is activated for the 1st time)
*
* @since 1.0
*/
function atom_setup_ads(){
$ads = (array)atom_get_options('advertisments');
if(!empty($ads)) new AtomAds($ads);
}
/**
* Set up the theme settings
* This should only run once (after the theme is activated for the 1st time)
*
* @since 1.0
*/
function atom_setup_options() {
// remove old settings
atom_remove_options();
// update the db with the default settings
atom_update_options(atom_default_settings());
define('INSTALLING_ATOM', true);
/*/ add our link in the blogroll if it doesn't exist -- only runs on 1st theme install -- removed, some function is missing
$found = false;
$links = get_bookmarks(array('hide_invisible' => 0));
foreach ($links as $link)
if($link->link_url == 'http://digitalnature.ro/') $found = true;
if(!$found)
wp_insert_link(array(
'link_name' => 'Digital Nature',
'link_url' => 'http://digitalnature.ro/',
'link_rss' => 'http://digitalnature.ro/feed/'
));
//*/
// action hook, probably useless
atom("setup_options");
}
/**
* Synchronize theme settings (eg. after updating)
*
* @since 1.0
*/
function atom_verify_options(){
$default_settings = atom_default_settings();
$current_settings = atom_get_options();
// if settings are not present (new theme install), load the defaults
if(!$current_settings):
atom_setup_options();
add_action('admin_notices', 'atom_theme_install_notification');
// update permalink structure
add_action('wp', create_function('', "flush_rewrite_rules();"));
atom_add_debug_message('New theme install. Default settings were installed');
else:
// only go further if the theme version from the database differs from the one in the theme files
if (version_compare($current_settings['theme_version'], THEME_VERSION, '!=')):
// check for new settings and load defaults
foreach($default_settings as $option => $value)
if(!array_key_exists($option, $current_settings)) $current_settings[$option] = $default_settings[$option];
// remove deprecated options
foreach($current_settings as $option => $value)
if(!array_key_exists($option, $default_settings)) unset($current_settings[$option]);
// update theme version
$current_settings['theme_version'] = THEME_VERSION;
atom_update_options($current_settings);
// update permalink structure
add_action('wp', create_function('', "flush_rewrite_rules();"));
atom_add_debug_message('Theme updated. Settings were synchronized');
endif;
endif;
}
/**
* First theme install notification message
*
* @since 1.0
*/
function atom_theme_install_notification(){ ?>
theme settings page.'), THEME_NAME, 'a href="'.get_admin_url('theme-settings').'"'); ?>
ID)) $layout = get_post_meta($post->ID, 'layout', true);
// custom page templates - lower priority
if (empty($layout) && (is_single() || is_page()) && ($page_template = sanitize_html_class(str_replace(array('page-', '.php'), '', get_post_meta($post->ID, '_wp_page_template', true)))))
if(in_array($page_template, atom_available_layout_types())) $layout = $page_template;
// if no template is defined so far, revert to the global layout option from the theme settings - lowest priority
if(empty($layout)) $layout = atom_get_options('layout');
endif;
if(!atom_preview_mode()):
$s1_active = ($layout != 'col-1') ? atom_is_active_area('sidebar-1') : false;
$s2_active = ($layout != 'col-1' && $layout != 'col-2-left' && $layout != 'col-2-right') ? atom_is_active_area('sidebar-2') : false;
// revert to a different layout if the current area is empty (or no widgets are visible)
if(!$s1_active && ($layout != 'col-1')) $layout = 'col-1';
if(!$s2_active && ($layout == 'col-3' || $layout == 'col-3-left')) $layout = $s1_active ? 'col-2-left' : 'col-1';
if(!$s2_active && ($layout == 'col-3' || $layout == 'col-3-right')) $layout = $s1_active ? 'col-2-right' : 'col-1';
endif;
return $layout;
}
/**
* Formats and outputs the current page document title
*
* @since 1.0
* @global $wp_query object
*
* @param string $separator Optional. Title separator. eg. " | ", " - " etc...
*/
function atom_document_title($separator = " « "){
global $wp_query;
$doctitle = get_bloginfo('name');
$desc = get_bloginfo('description');
if (is_front_page() && is_home() && !empty($desc)):
$doctitle .= $separator.$desc;
elseif (is_home() || is_singular()):
$id = $wp_query->get_queried_object_id();
if($meta = get_post_meta($id, 'title', true)) $doctitle .= $separator.$meta;
$doctitle .= (empty($meta) && is_front_page() && !empty($desc)) ? $separator.$desc : $separator.get_post_field('post_title', $id);
elseif (is_archive()):
if (is_category() || is_tag() || is_tax()):
$term = $wp_query->get_queried_object();
$doctitle .= $separator.$term->name;
elseif (is_author()):
$doctitle .= $separator.get_the_author_meta('display_name', get_query_var('author'));
elseif (is_date()):
if (is_day())
$doctitle .= $separator.sprintf(_a('Archive for %s'), get_the_time(apply_filters('doc_title_archive_day_format', 'F jS, Y')));
elseif (get_query_var('w'))
$doctitle .= $separator.$separator.sprintf(_a('Archive for week %1$s of %2$s'), get_the_time('W'), get_the_time('Y'));
elseif (is_month())
$doctitle .= $separator.sprintf(_a('Archive for %s'), single_month_title(' ', false));
elseif (is_year())
$doctitle .= $separator.sprintf(_a('Archive for year %s'), get_the_time('Y'));
endif;
elseif (is_search()):
$doctitle .= $separator.sprintf(_a('Search results for %s'),'"'.get_search_query().'"');
elseif (is_404()):
$doctitle .= $separator._a('404 Not Found');
endif;
/* If paged. */
if ((($page = $wp_query->get('paged')) || ($page = $wp_query->get('page'))) && $page > 1 && !is_404())
$doctitle .= $separator.sprintf(_a('Page %s'), $page);
/* if comment page... */
if (get_query_var('cpage'))
$doctitle .= $separator.sprintf(_a('Comment Page %s'), get_query_var('cpage'));
/* Apply the wp_title filters so we're compatible with plugins. */
$doctitle = apply_filters('wp_title', $doctitle, $separator, '');
echo $doctitle;
}
/**
* Generates and outputs the current page meta description field
*
* @since 1.0
* @global $wp_query object
*/
function atom_meta_description() {
if(!atom_get_options('meta_description')) return false;
global $wp_query;
// blog description on the homepage
if (is_home()): $description = get_bloginfo('description');
// single pages?
elseif (is_singular()):
// custom field, if present
$description = get_metadata('post', $wp_query->post->ID, 'description', true);
// if not, and we're on a static homepage use the blog description
if (empty($description) && is_front_page()):
$description = get_bloginfo('description');
// otherwise use the post excerpt
elseif (empty($description)):
$description = get_post_field('post_excerpt', $wp_query->post->ID);
endif;
// archive pages?
elseif (is_archive()):
// author bio on author pages
if (is_author()):
$description = get_the_author_meta('description', get_query_var('author'));
// taxonomy term description on category/tags/etc...
elseif (is_category() || is_tag() || is_tax()):
$description = term_description('', get_query_var('taxonomy'));
endif;
endif;
if (!empty($description)):
// remove html formatting
$description = str_replace(array("\r", "\n", "\t"),'',esc_attr(strip_tags($description)));
// output (and allow user to change the content trough a filter hook)
echo ''.PHP_EOL;
endif;
}
/**
* Append the Atom version in the generator meta field (xhtml only)
*
* @since 1.0
*
* @param string $generator
* @param string $type
*/
function atom_meta_generator($generator, $type){
return '';
}
/**
* Output the site logo HTML
*
* @since 1.0
*
* @param string $image_path Image URL
* @param string $image_size Optional. Image size (WxH)
*/
function atom_logo($image_path = '', $image_size = ''){
atom("before_logo");
if(!$image_path):
$image_path = atom_get_options('logo');
// if(!$image_size): $image_size = atom_get_options('logo_size'); endif; @todo auto image-size
endif;
if($image_size) $image_size = 'width="'.substr($image_size, 0, strpos($image_size, "x")).'" height="'.substr($image_size, strpos($image_size, 'x')+1).'"';
$sitename = apply_filters('atom_logo_title', get_bloginfo('name'));
$siteurl = apply_filters('atom_logo_url', home_url());
$image_path = apply_filters('atom_logo_image', $image_path);
// h1 only on the front/home page, for seo reasons
$tag = (is_home() || is_front_page()) ? 'h1' : 'div';
$output = "<{$tag} id=\"logo\">\n";
if($image_path): // logo image?
$output .= "";
else:
$words = explode(" ", $sitename); // we get a special treat if the logo is made out of 2 or 3 words
if(!empty($words[1]) && empty($words[3])):
$words[1] = "{$words[1]}";
$sitename = implode(" ", $words); // leave the space here and remove it trough css to avoid seo problems
endif;
$output .= "".apply_filters('atom_logo_title_html', $sitename)."";
endif;
$output .= "{$tag}>";
echo apply_filters('atom_logo', $output, $siteurl, $sitename);
atom("after_logo");
}
/**
* Generates semantic classes for BODY element (mostly based on the sandbox theme)
*
* @since 1.0
* @global $wp_query object
* @global $current_user object
*
* @param array $classes
*/
function atom_body_class($classes){
global $wp_query, $current_user, $is_lynx, $is_gecko, $is_IE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone;
$s = atom_get_options();
// Special classes for BODY element when a single post
if (is_single()):
$postname = $wp_query->post->post_name;
the_post();
// post title
$classes[] = "title-{$postname}";
// Adds category classes for each category on single posts
if ($cats = get_the_category()) foreach ($cats as $cat) $classes[] = "category-{$cat->slug}";
// Adds tag classes for each tags on single posts
if ($tags = get_the_tags()) foreach ($tags as $tag) $classes[] = "tag-{$tag->slug}";
// Adds author class for the post author
$classes[] = "author-".sanitize_title_with_dashes(strtolower(get_the_author_meta('user_login')));
rewind_posts();
elseif (is_page()): // Page author for BODY on 'pages'
$pagename = $wp_query->post->post_name;
the_post();
$classes[] = "page-{$pagename}";
$classes[] = "author-".sanitize_title_with_dashes(strtolower(get_the_author_meta('user_login')));
rewind_posts();
endif;
// generate layout class
$classes[] = atom_get_layout_type();
// fixed/fluid page
$classes[] = $s['page_width'];
// detect browser
if($is_lynx) $browser = 'lynx';
elseif($is_gecko) $browser = 'gecko';
elseif($is_opera) $browser = 'opera';
elseif($is_NS4) $browser = 'ns4';
elseif($is_safari) $browser = 'safari';
elseif($is_chrome) $browser = 'chrome';
elseif($is_IE) $browser = 'ie';
else $browser = 'unknown';
if($is_iphone) $browser .= '-iphone';
$classes[] = "browser-{$browser}";
return $classes;
}
/**
* Generates semantic classes for posts
*
* @since 1.0
* @global $wp_query object
*
* @param array $classes
*/
function atom_post_class($classes){
global $wp_query;
$current_post = $wp_query->current_post + 1;
// post alt
$classes[] = "count-{$current_post}";
$classes[] = ($current_post % 2) ? 'odd' : 'even alt';
// clear-block class, omitted in thumbnail-only mode
if(atom_thumbnails_only() && !atom_is_sticky()) $classes[] = 'thumb-only'; else $classes[] = 'clear-block';
// thumbnail classes
if(atom_get_options('post_thumbs') && !atom_is_sticky() && !is_singular()) $classes[] = 'thumb-'.atom_get_options('post_thumbs_mode');
// author
$classes[] = 'author-'.sanitize_html_class(get_the_author_meta('user_nicename'), get_the_author_meta('ID'));
// password-protected?
if (post_password_required()) $classes[] = 'protected';
// first/last class ("first" and "count-1" are the same)
if($current_post == 1) $classes[] = 'first'; elseif($current_post == $wp_query->post_count) $classes[] = 'last';
return $classes;
}
/**
* Generates semantic classes for comments
*
* @since 1.0
* @global $post object
* @global $comment object
*
* @param array $classes
*
* @todo Add author country class
*/
function atom_comment_class($classes) {
global $post, $comment;
// avatars enabled?
if(atom_get_options('show_avatars')) $classes[] = 'with-avatars';
// user roles
if($comment->user_id > 0):
$user = new WP_User($comment->user_id);
if (is_array($user->roles))
foreach ($user->roles as $role) $classes[] = "role-{$role}";
$classes[] = 'user-'.sanitize_html_class($user->user_nicename, $user->ID);
else:
$classes[] = 'reader name-'.sanitize_title(get_comment_author());
endif;
// needs moderation?
if($comment->comment_approved == '0') $classes[] = "awaiting-moderation";
// karma-related
if(atom_is_comment_buried()) $classes[] = "buried";
if(atom_get_options('comment_karma'))
if($comment->comment_karma < '0') $classes[] = "karma-negative"; elseif($comment->comment_karma > '0') $classes[] = "karma-positive";
// country code, if available
if(atom_get_options('comment_flags') && !isset($comment->country))
$comment->country = atom_get_country($comment->comment_author_IP);
if($comment->country) $classes[] = "country-{$comment->country['code']}";
return $classes;
}
/**
* Gets the country info based on a IP address
*
* @since 1.0
*
* @param string $ip User IP Address
* @return array Country Name and Country Code
*
* @todo update the ip2c database
*/
function atom_get_country($ip) {
require_once('ip2c/ip2c.php');
$ip2c = wp_cache_get("atom_ip2c");
if($ip2c === false):
$ip2c = new ip2country(TEMPLATEPATH.'/core/ip2c/ip-to-country.bin');
wp_cache_set("atom_ip2c", $ip2c);
endif;
$country = $ip2c->get_country($ip);
if($country):
$code = strtolower($country['id2']);
$name = ucwords(strtolower($country['name']));
return array('code' => $code, 'name' => $name);
else:
return false;
endif;
}
/**
* Generates page navigation links
* based on WP-Pagenavi - http://wordpress.org/extend/plugins/wp-pagenavi
*
* @since 1.0
* @global $wp_query object
*
* @param string $class Extra classes to output
* @param bool $pages Show numbered page navigation
* @param int $pages_to_show Numbered page links to show
* @param bool $extended If true, adds 3 extra page links for every 10nth page
* @param bool $status Show status text (eg. page X out of Y)
*/
function atom_pagenavi($class = '', $pages = true, $pages_to_show = 5, $extended = false, $status = false){
// don't show on single pages
if (is_single()) return false;
global $wp_query;
$posts_per_page = intval(get_query_var('posts_per_page'));
$paged = intval(get_query_var('paged'));
$request = $wp_query->request;
$numposts = $wp_query->found_posts;
$max_page = $wp_query->max_num_pages;
if ($max_page <= 1) return false; // dont show if we only have one page
if (empty($paged)) $paged = 1;
$larger_page_to_show = 3;
$larger_page_multiple = 10;
$pages_to_show_minus_1 = $pages_to_show - 1;
$half_page_start = floor($pages_to_show_minus_1/2);
$half_page_end = ceil($pages_to_show_minus_1/2);
$start_page = $paged - $half_page_start;
if ($start_page <= 0) $start_page = 1;
$end_page = $paged + $half_page_end;
if (($end_page - $start_page) != $pages_to_show_minus_1) $end_page = $start_page + $pages_to_show_minus_1;
if ($end_page > $max_page):
$start_page = $max_page - $pages_to_show_minus_1;
$end_page = $max_page;
endif;
if ($start_page <= 0) $start_page = 1;
$out = '';
if($status) $out .= ''.sprintf(_a('Page %1$s of %2$s'), $paged, $max_page).'';
// add classes to prev/next so they can be styled
add_filter('previous_posts_link_attributes', create_function('', 'return \'class="previous"\'; '));
add_filter('next_posts_link_attributes', create_function('', 'return \'class="next"\'; '));
$out .= get_previous_posts_link(_a('« Previous'));
// numbered page links
if($pages):
if ($start_page >= 2 && $pages_to_show < $max_page):
$out .= '1';
$out .= '...';
endif;
$larger_pages_array = array();
if ($larger_page_multiple)
for ($i = $larger_page_multiple; $i <= $max_page; $i += $larger_page_multiple) $larger_pages_array[] = $i;
if($extended):
$larger_page_start = 0;
foreach ($larger_pages_array as $larger_page)
if ($larger_page < $start_page && $larger_page_start < $larger_page_to_show):
$out .= ''.$larger_page.'';
$larger_page_start++;
endif;
endif;
for ($i = $start_page; $i <= $end_page; $i++)
if ($i == $paged) $out .= ''.$i.'';
else $out .= ''.$i.'';
if($extended):
$larger_page_end = 0;
foreach ($larger_pages_array as $larger_page)
if ($larger_page > $end_page && $larger_page_end < $larger_page_to_show):
$out .= ''.$larger_page.'';
$larger_page_end++;
endif;
endif;
if ($end_page < $max_page):
$out .= '...';
$out .= ''.$max_page.'';
endif;
endif;
$out .= get_next_posts_link(_a('Next »'), $max_page);
?>
60 * 60 * 24 * 365, // 31,536,000 seconds
'month' => 60 * 60 * 24 * 30, // 2,592,000 seconds
'week' => 60 * 60 * 24 * 7, // 604,800 seconds
'day' => 60 * 60 * 24, // 86,400 seconds
'hour' => 60 * 60, // 3600 seconds
'minute' => 60, // 60 seconds
'second' => 1 // 1 second
);
$newer_date = ($newer_date == false) ? (time()+(60*60*atom_get_options("gmt_offset"))) : $newer_date;
$since = $newer_date - $older_date;
foreach ($chunks as $key => $seconds)
if (($count = floor($since / $seconds)) != 0) break;
$messages = array(
'year' => _an('%s year ago', '%s years ago', $count),
'month' => _an('%s month ago', '%s months ago', $count),
'week' => _an('%s week ago', '%s weeks ago', $count),
'day' => _an('%s day ago', '%s days ago', $count),
'hour' => _an('%s hour ago', '%s hours ago', $count),
'minute' => _an('%s minute ago', '%s minutes ago', $count),
'second' => _an('%s second ago', '%s seconds ago', $count),
);
return sprintf($messages[$key],$count);
}
/**
* Removes HTML tags from a string, including the content between them
* from http://www.php.net/manual/en/function.strip-tags.php#86964
*
* @since 1.0
*
* @param string $text What to filter
* @param string $tags Allowed tags.
* @param bool $invert Remove the $tags above, allow others ($tags becomes Disallowed tags)
* @return string Filtered content
*/
function atom_strip_tags_content($text, $tags = '', $invert = false) {
preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($tags), $tags);
$tags = array_unique($tags[1]);
if(is_array($tags) AND count($tags) > 0){
if($invert == false)
return preg_replace('@<(?!(?:'.implode('|', $tags).')\b)(\w+)\b.*?>.*?\1>@si', '', $text);
else
return preg_replace('@<('.implode('|', $tags).')\b.*?>.*?\1>@si', '', $text);
}
elseif($invert == false) {
return preg_replace('@<(\w+)\b.*?>.*?\1>@si', '', $text);
}
return $text;
}
/**
* Filters content based on specific parameters, and appends a "read more" link if needed.
* Based on the "Advanced Excerpt" plugin by Bas van Doren - http://sparepencil.com/code/advanced-excerpt/
*
* @since 1.0
*
* @param string $content What to filter, defaults to get_the_content(); should be left empty if we're filtering post content
* @param array $args Optional arguments (limit, allowed tags, enable/disable shortcodes, read more link)
* @return string Filtered content
*/
function atom_filter_content($content = null, $args = array()){
// get the theme settings
$args = wp_parse_args($args, array(
'limit' => atom_get_options('post_content_mode'),
'allowed_tags' => array('a', 'abbr', 'acronym', 'address', 'b', 'big', 'blockquote', 'cite', 'code', 'dd', 'del', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'ins', 'li', 'ol', 'p', 'pre', 'q', 'small', 'span', 'strong', 'sub', 'sup', 'tt', 'ul'),
'shortcodes' => false,
'more' => ''._a('More >').'',
));
extract(apply_filters('atom_content_filter_args', $args, $content), EXTR_SKIP);
$text = isset($content) ? $content : get_the_content();
if(!$shortcodes) $text = strip_shortcodes($text);
if(!isset($content)) $text = apply_filters('the_content', $text);
// From the default wp_trim_excerpt():
// Some kind of precaution against malformed CDATA in RSS feeds I suppose
$text = str_replace(']]>', ']]>', $text);
// Strip HTML if allow-all is not set
if(!in_array('ALL', $allowed_tags)):
if(count($allowed_tags) > 0) $tag_string = '<'.implode('><', $allowed_tags).'>'; else $tag_string = '';
$text = strip_tags($text, $tag_string); // @todo: find a way to use the function above (strip certain tags with the content between them)
endif;
// Skip if text is already within limit
if($limit == 0 || $limit >= count(preg_split('/[\s]+/', strip_tags($text)))) return $text;
// Split on whitespace and start counting (for real)
$text_bits = preg_split('/([\s]+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$in_tag = false;
$n_words = 0;
$text = '';
foreach($text_bits as $chunk):
if(!$in_tag || strpos($chunk, '>') !== false) $in_tag = (strrpos($chunk, '>') < strrpos($chunk, '<'));
// Whitespace outside tags is word separator
if(!$in_tag && '' == trim($chunk)) $n_words++;
if($n_words >= $limit && !$in_tag) break;
$text .= $chunk;
endforeach;
$text = trim(force_balance_tags($text));
if($more):
$more = " {$more}";
if(($pos = strpos($text, '', strlen($text) - 7)) !== false):
// Stay inside the last paragraph (if it's in the last 6 characters)
$text = substr_replace($text, $more, $pos, 0);
else:
// If
is an allowed tag, wrap read more link for consistency with excerpt markup
if(in_array('ALL', $allowed_tags) || in_array('p', $allowed_tags))
$more = "
{$more}
";
$text = $text.$more;
endif;
endif;
return $text;
}
/**
* Get the user avatar based on his email address
*
* @since 1.0
*
* @param string $email Valid Email Address
* @param int $size Optional. Image size
* @param string $default Default image
* @param string $alt Alternate text
* @return string Avatar image (HTML)
*/
function atom_get_avatar($email, $size = 48, $default = '', $alt = false){
// if today is April 1st show a pony :)
if(date('m-d') == '04-01') return '';
// if not, display the user's gravatar
else return get_avatar($email, $size, $default, $alt);
}
/**
* Get the first image from a post
*
* @since 1.0
* @global $post object
*
* @param object $source post object
* @return string Image (HTML)
*/
function atom_get_first_post_image($source = false) {
global $post;
if (!$source) $source = $post;
$first_img = '';
$output = preg_match_all('//i', $source->post_content, $matches);
$first_img = $matches [1][0];
return $first_img;
}
/**
* Check if a post thumbnail needs to be updated (missing size)
*
* @since 1.3
* @global $_wp_additional_image_sizes array Image sizes
*
* @param int $attachment_id Attachment ID
* @param string $size Thumbnail size
* @return bool
*/
function atom_thumbnail_needs_regeneration($attachment_id, $size = 'post-thumbnail'){
global $_wp_additional_image_sizes;
// no such size, probably fake request
if(!isset($_wp_additional_image_sizes[$size])) return false;
$requested_width = $_wp_additional_image_sizes[$size]['width'];
$requested_height = $_wp_additional_image_sizes[$size]['height'];
$meta = wp_get_attachment_metadata($attachment_id);
if(!is_array($meta)) return false;
// small image? WP doesn't enlarge images
if(!isset($meta['sizes'][$size]) && ($meta['width'] < $requested_width) && ($meta['height'] < $requested_height)) return false;
// check if we have a size match
if(isset($meta['sizes'][$size]['width']) && isset($meta['sizes'][$size]['height']))
if(($meta['sizes'][$size]['width'] == $requested_width) || ($meta['sizes'][$size]['height'] == $requested_height)) return false;
return true;
}
/**
* Output the post thumbnail
* Replaces get_the_post_thumbnail()
*
* @since 1.0
* @global $post object Current Post
* @global $_wp_additional_image_sizes array Image sizes
*
* @param int $post_id Optional. Post ID
* @param string $size Optional. Thumbnail size
* @return string Thumbnail image
*/
function atom_get_post_thumb($post_id = null, $size = 'post-thumbnail', $attr = ''){
global $post, $_wp_additional_image_sizes;
$post_id = ($post_id === null) ? $post->ID : $post_id;
$html = '';
$width = $_wp_additional_image_sizes[$size]['width'];
$height = $_wp_additional_image_sizes[$size]['height'];
// $t = get_post_meta($post_id, '_thumbnail_id', true);
$t = get_post_thumbnail_id($post_id);
if(empty($t) && atom_get_options('post_thumb_auto')):
$attachments = get_children(array('post_parent' => $post_id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID'));
$attachment = array_shift($attachments);
$t = ($attachment ? $attachment->ID : false);
endif;
$done = false;
if(!empty($t))
if(atom_thumbnail_needs_regeneration($t, $size)):
$html = "";
else:
do_action('begin_fetch_post_thumbnail_html', $post_id, $t, $size);
$html = wp_get_attachment_image($t, $size, false, $attr);
do_action('end_fetch_post_thumbnail_html', $post_id, $t, $size);
endif;
if(!$html) $html = "";
return apply_filters('post_thumbnail_html', $html, $post_id, $t, $size, $attr);
}
/**
* Update a post thumbnail (generate new image sizes)
* Should be called trough ajax because it requires a lot of cpu and it will slow down page loading
* - based on the 'regenerate thumbnails' plugin by Viper007Bond
*
* @since 1.0
*
* @param int $t Thumbnail (attachment) ID
* @param string $size Optional. Thumbnail size
* @return bool true if new meta data was generated, false otherwise
*/
function atom_update_post_thumb($attachment_id, $size = 'post-thumbnail'){
if(!atom_get_options('generate_thumbs') || !atom_thumbnail_needs_regeneration($attachment_id, $size)) return false;
$full_size_path = get_attached_file($attachment_id);
// The originally uploaded image file cannot be found at $full_size_path
if($full_size_path === false || !file_exists($full_size_path)) return false;
require_once(ABSPATH.'/wp-admin/includes/image.php');
@set_time_limit(900); // 5 minutes per image should be PLENTY
$metadata = wp_generate_attachment_metadata($attachment_id, $full_size_path);
if(is_wp_error($metadata)) return false; // $metadata->get_error_message();
wp_update_attachment_metadata($attachment_id, $metadata);
return true;
}
/**
* Retrieve the terms for a post.
* uses wp_get_post_terms()
*
* @since 1.0
* @global $id int Current Post ID
*
* @param int $post_id Post ID (Optional inside the loop, required outside the loop)
* @param string $taxonomy Term Taxonomy (optional, defaults to tags)
* @return array Terms as a array of links
*/
function atom_get_post_terms($post_id = NULL, $taxonomy = 'post_tag'){
global $id;
$post_id = (NULL === $post_id) ? $id : $post_id;
$terms = wp_get_post_terms($post_id, $taxonomy);
if ($terms):
$output = array();
foreach($terms as $term)
$output[] .= ''.apply_filters('atom_term_name', $term->name, $term, $taxonomy, $post_id).'';
return $output;
endif;
return array();
}
/**
* Check if a post is marked as "sticky"
* same as is_sticky(), but also checks if the post is on the home page
*
* @since 1.0
*
* @return bool True or false
*/
function atom_is_sticky(){
return(is_sticky() && is_home()); // sticky post? (we consider it sticky only if it's on the homepage)
}
/**
* Output the post thumbnail
*
* @since 1.0
*/
function atom_post_thumb($classes = 'post-thumb'){
if(!atom_is_option_enabled('post_thumbs') || !atom_get_options('post_thumbs') || atom_is_sticky()) return false;
$show_tip = (atom_thumbnails_only() || !atom_get_options('post_content'));
if($show_tip) $classes .= ' tt';
$tip_content = (atom_thumbnails_only() ? get_the_title() : strip_tags(get_the_excerpt()));
$title = ($show_tip ? $tip_content : sprintf(_a('Permanent Link: %s'), the_title_attribute('echo=0')));
?>
0)
if(strlen($title) > $character_limit) $title = substr($title, 0, $character_limit)."...";
return $title;
}
/**
* Format and output the post title
*
* @since 1.2
*
* @param string $tag HTML Tag to wrap into
* @param string $classes Tag classes
* @param string $character_limit Limit to X characters
*/
function atom_post_title($tag = NULL, $classes = 'title', $character_limit = 0){
global $id;
$title = atom_get_post_title($id, $character_limit);
if(!atom_get_options('post_title') || empty($title)) return;
$opening_tag = $closing_tag = '';
if($tag):
$opening_tag = "<{$tag} class=\"{$classes}\">";
$closing_tag = "{$tag}>";
endif;
echo "{$opening_tag}{$title}{$closing_tag}";
}
/**
* Retrieve the post author
*
* @since 1.0
*
* @return string Post Author as link
*/
function atom_get_post_author(){
return ''.get_the_author().'';
}
/**
* Return the post date (inside the loop only)
*
* @since 1.0
*
* @param string $mode
*/
function atom_get_post_date($mode = 'relative'){
global $post;
return ($mode == 'relative' ? atom_time_since(abs(strtotime("{$post->post_date} GMT"))) : get_the_date($mode));
}
/**
* Output the print link
*
* @since 1.0
*
* @param string $title Link Title
*/
function atom_print_link($title = false){
if(!atom_get_options('single_print')) return false;
?>
post_type}");
get_template_part($template, $post->post_type);
atom("after_{$post->post_type}");
}
/**
* Output a post preview
* to be used only inside the loop!
*
* @since 1.0
* @global $post object
*
* @param array $opts Optional. Override settings
* @todo add fade effect on thumbnails
*/
function atom_print_preview($opts = false){
global $post;
?>
's here
$output = apply_filters('atom_social_media_links', $output);
if($output) echo "
\n{$output}
";
}
/**
* Output posts related to the current post, by tags
*
* @since 1.0
*
* @global $post object
* @global $id int
*
* @param int $post_id Optional. Post ID
* @param int $count Optional. Max. number of posts to retrieve
*
* @return string|bool A list of related posts (HTML), or false if no related posts were found
*
* @todo add fade effect on thumbnails
* @todo move the html to a template
*/
function atom_get_related_posts($post_id = NULL, $count = 10, $template = 'related'){
global $post, $id;
$post_id = (NULL === $post_id) ? $id : $post_id;
$output = '';
$tags = wp_get_post_tags($post_id);
if(!empty($tags)):
$tag_ids = array();
foreach($tags as $tag) $tag_ids[] = $tag->term_id;
$query = array('tag__in' => $tag_ids, 'post__not_in' => array($post_id), 'posts_per_page' => $count, 'caller_get_posts' => 1);
$related_posts = new WP_Query();
$related_posts->query($query);
if($related_posts):
while ($related_posts->have_posts()):
$related_posts->the_post();
$output .= "
\n";
endwhile;
endif;
wp_reset_query();
endif;
if($output) return $output; else return atom_add_debug_message("No related posts found for post {$post_id}.");
}
/**
* Output Author Information
* If used outside the loop, a Author ID must be specified
*
* @since 1.0
*
* @global $post object
*
* @param int $authorID Author ID (Optional inside the loop)
*
* @return string Author Info (HTML)
*/
function atom_get_author_info($author_id = NULL){
global $post;
$output = '';
$description = false;
if(!$author_id) $author_id = $post->post_author;
$author_name = get_the_author_meta('display_name', $author_id);
$post_count = ''.sprintf(_an('%s post', '%s posts', count_user_posts($author_id)), count_user_posts($author_id)).'';
// try to get the 'author' custom field first
if(!($description = force_balance_tags(wpautop(get_post_meta($post->ID, 'author', true)))))
if($description = get_the_author_meta('description', $author_id)) $description = "
{$description}
";
// empty, add a placeholder.
if(!$description) $description = "
';
$output .= convert_smilies($description);
$output .= ''.sprintf(_a("%s's RSS Feed"), $author_name).'';
return $output;
}
//
/**
* Output the comment form
* Almost the same as WP's comment_form(); modified to match the theme's comment form layout style
*
* @since 1.0.2
*
* @global $post object
*
* @param array $args
* @param int $post_id
*
* @todo: Add more arguments to $args(
*/
function atom_comment_form($args = array(), $post_id = NULL){
global $user_identity, $id, $allowedtags;
?>
$attributes)
$allowed .= ''.htmlentities("<{$tag}>").' ';
$commenter = wp_get_current_commenter();
$req = atom_get_options('require_name_email');
$aria_req = ($req ? " aria-required='true'" : '');
$labels = array('author' => _a('Name').($req ? " "._a("(required)") : ''),
'email' => _a('E-mail').($req ? " "._a("(required, will not be published)") : _a("(will not be published)")),
'url' => _a('Website'));
$fields = array(
'author' => (!atom_get_options('jquery') ? ' ' : '').'',
'email' => (!atom_get_options('jquery') ? ' ' : '').'',
'url' => (!atom_get_options('jquery') ? ' ' : '').''
);
$defaults = array(
'fields' => apply_filters('comment_form_default_fields', $fields),
'comment_field' => '',
'logged_in_as' => sprintf(_a('Logged in as %s.'), ''.$user_identity.'').' '._a('Log out?').'',
'id_form' => 'commentform',
'id_submit' => 'submit',
'cancel_reply_link' => _a( 'Cancel reply' ),
'label_submit' => _a('Post Comment'),
/*/ @todo: find a way to integrate these as well
'title_reply' => __('Leave a Reply'),
'title_reply_to' => __('Leave a Reply to %s'),
'comment_notes_before' => '
'.__( 'Your email address will not be published.').($req ? $required_text : '').'
',
'comment_notes_after' => '
'.sprintf(__('You may use these HTML tags and attributes: %s'), ''.allowed_tags().' ').'
',
'must_log_in' => '
'. sprintf(__('You must be logged in to post a comment.'), wp_login_url(apply_filters('the_permalink', get_permalink($post_id)))) .'
tag
* Can only be used inside the comment template
*
* @since 1.3
*
* @global $comment
*
* @param string $rel
*/
function atom_get_comment_author($rel = 'nofollow'){
global $comment;
// get country based on IP
if(atom_get_options('comment_flags') && !isset($comment->country))
$comment->country = atom_get_country($comment->comment_author_IP);
if (get_comment_author_url())
$output = ''.get_comment_author().'';
else $output = ''.get_comment_author().'';
if($comment->country) $output .= "country['name']}\" class=\"flag {$comment->country['code']}\"> ";
return apply_filters("atom_comment_author", $output, $comment);
}
/**
* Output the comment author's avatar
* Can only be used inside the comment template
*
* @since 1.0
*
* @global $comment
*
* @param string $classes
*/
function atom_comment_avatar($classes = 'avatar'){
if(atom_get_options('show_avatars')):
global $comment;
echo '
';
// pass arguments to wp_list_pages (most of them are ignored)
$page_list_args = (array)$args;
// if the front page is a page, add it to the exclude list
if(atom_get_options('show_on_front') == 'page') $page_list_args['exclude'] = atom_get_options('page_on_front');
// other extra arguments
$page_list_args['echo'] = false;
$page_list_args['title_li'] = '';
// get page list
$items .= str_replace(array("\r", "\n", "\t"), '', wp_list_pages($page_list_args));
// attributes
if(!empty($args->menu_id)) $slug = $args->menu_id; else $slug = 'menu-'.$args->slug;
$attributes = ' id="'.$slug.'"';
$attributes .= $args->menu_class ? ' class="'.$args->menu_class.'"' : '';
$nav_menu .= '
';
$nav_menu .= $items;
$nav_menu .= '
';
if($show_container) $nav_menu .= ''.$args->container.'>';
$nav_menu = apply_filters('wp_page_menu', $nav_menu, $args);
if($args->echo) echo $nav_menu; else return $nav_menu;
}
/**
* Category navigation, not used by default (maybe some child themes will use it)
* Contents are the home link and a list of categories/sub-categories
* NEEDS UPDATE!
*
* @since 1.2
*/
function atom_category_menu($args){
$menu = '';
$args['echo'] = false;
$args['title_li'] = '';
$args['walker'] = new atom_walker_terms();
// add 'home' menu item
$menu .= '
\n";
echo $menu;
}
/**
* Renders a simple block template (really basic templating system). Replaces {var} with $parameters['var'];
* original was from: Fabien Potencier's "Design patterns revisited with PHP 5.3" (page 45), but I replaced it with a function that works in php 4.x as well
*
* @param string $string
* @param array $parameters
*
* @return string
*/
function atom_render_template($string, $parameters = array()){
foreach($parameters as $find => $replace):
$finds[] = '{'.$find.'}';
$replaces[] = $replace;
endforeach;
return str_replace($finds, $replaces, $string);
}
/**
* Output the "Footer Content" field from the theme settings
*/
function atom_footer_content(){
echo apply_filters('atom_footer_content', do_shortcode(stripslashes(atom_get_options('footer_content'))));
}
/**
* Retrieves all attached images to a post
*
* @since 1.2
*
* @param int $post_id Post ID.
* @param string $order Order, ASC/DESC
* @param string $orderby Order byl
*
* @return array results
*/
function atom_get_gallery($post_id = NULL, $order = 'ASC', $orderby = 'menu_order ID'){
global $post;
$post_id = (NULL === $post_id) ? $post->ID : $post_id;
return get_children(array('post_parent' => $post_id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby));
}
/**
* Replaces wp's category walker (WP's default walker doesn't allow much control over the output and the css classes provided are useless)
* All content inside the list item can be formatted trough the "link-callback" function
*
* @since 1.2
*/
class atom_walker_terms extends Walker{
var $tree_type = 'category';
var $db_fields = array('parent' => 'parent', 'id' => 'term_id');
function start_lvl(&$output, $depth, $args){
$indent = str_repeat("\t", $depth);
$output .= "$indent
\n";
}
}
/**
* Output the meta sections (comments, related posts, about the author etc) - not to be confused with the post metadata
* Notes:
* - Should only be used only inside single pages
* - Templates for custom post types (eg. 'meta-movie.php') have priority over meta.php
*
* @since 1.2
*
* @global $post
*
* @param string $template Optional. Can override the 'meta' template (for eg. within the [query] shortcode)
*/
function atom_meta($template = 'meta'){
global $post;
// intense debate
if(file_exists($custom_template = apply_filters('comments_template', ''))) require($custom_template);
// default template
else get_template_part($template, $post->post_type);
atom("after_{$post->post_type}_meta");
}
/**
* Get the comment count for a post.
* If used outside the meta template it will return a imprecise comment count (counting both comments and pings)
*
* @since 1.2
*
* @return int comment count
*/
function atom_comment_count(){
global $wp_query, $post;
if(isset($wp_query->comments_by_type)) return count($wp_query->comments_by_type['comment']);
elseif(isset($post->comment_count)) return $post->comment_count;
else return 0;
}
/**
* Get the ping+trackback count for a post
* If used outside the meta template it will return 0, as the comments for each post are not loaded yet
*
* @since 1.2
*
* @return int comment count
*/
function atom_ping_count(){
global $wp_query;
if(isset($wp_query->comments_by_type)) return count($wp_query->comments_by_type['pings']);
else return 0;
}
/**
* Get the comment filter search query
*
* @since 1.2
*
* @return string|bool
*/
function atom_get_comment_filter_query(){
if(isset($_POST['comment-filter']))
return esc_attr($_POST['comment-filter']);
return false;
}
/**
* Get all post's comments
* Replaces WP's comments_template(), so we can use the nice ajax comments feature
* @todo: reduce database usage, by finding a way to load only the requested comments instead of all comments. This can be done using LIMIT, but then we get the wrong comment/ping count :(
*
* @since 1.2
*
* @param int $post_id Optional post ID
* @return array comments
*/
function atom_get_comments($post_id = null){
global $wp_query, $withcomments, $post, $wpdb, $user_ID, $overridden_cpage, $comments;
$post_id = (null === $post_id) ? $post->ID : $post_id;
if(!(is_single() || is_page() || $withcomments) || empty($post)) return false;
$commenter = wp_get_current_commenter();
$comment_author = wp_specialchars_decode($commenter['comment_author'], ENT_QUOTES); // Escaped by sanitize_comment_cookies()
$comment_author_email = $commenter['comment_author_email']; // Escaped by sanitize_comment_cookies()
$comment_author_url = esc_url($commenter['comment_author_url']);
/*/ ajax comments - @todo
if(!$comments && atom_get_options('ajax_comments')):
global $post, $wpdb;
$comments = get_comments(array(
'type' => 'comment',
'post_id' => $post_id,
'status' => 'approve',
'number' => atom_get_options("ajax_comments_count")
));
endif;
/*/
$filter = atom_get_comment_filter_query() ? mysql_real_escape_string(atom_get_comment_filter_query()) : '';
if(!empty($filter)) $filter = "AND (comment_content LIKE '%%{$filter}%%' OR comment_author LIKE '%%{$filter}%%')";
// $limits = "LIMIT ".atom_get_options("ajax_comments_count");
// show non-approved comments based on the current user context
if(!current_user_can('moderate_comments'))
if($user_ID) $filter .= " AND (comment_approved = '1' OR (user_id = '{$user_ID}' AND comment_approved = '0'))";
elseif(empty($comment_author)) $filter .= " AND comment_approved = '1'";
else $filter .= " AND (comment_approved = '1' OR (comment_author = '".wp_specialchars_decode($comment_author, ENT_QUOTES)."' AND comment_author_email = '{$comment_author_email}' AND comment_approved = '0'))";
$comments = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->comments} WHERE comment_post_ID = %d {$filter} ORDER BY comment_date_gmt", $post_id));
// keep $comments for legacy's sake
$wp_query->comments = apply_filters('comments_array', $comments, $post_id);
$comments = &$wp_query->comments;
$wp_query->comment_count = count($wp_query->comments);
update_comment_cache($wp_query->comments);
$wp_query->comments_by_type = &separate_comments($comments);
$comments_by_type = &$wp_query->comments_by_type;
$overridden_cpage = false;
if ('' == get_query_var('cpage') && atom_get_options('page_comments')){
set_query_var('cpage', 'newest' == atom_get_options('default_comments_page') ? get_comment_pages_count() : 1);
$overridden_cpage = true;
}
return $comments;
}
/**
* Display a list of comments
*
* @since 1.2
*
* @param array $comments comments (required)
* @param array $args Optional arguments
*/
function atom_comments($comments, $args = array('type' => 'comment', 'callback' => 'atom_comment')){
if(empty($comments)) return;
wp_list_comments($args, $comments);
}
/**
* Display a list of pings
*
* @since 1.2
*
* @param array $comments comments (required)
* @param array $args Optional arguments
*/
function atom_pings($comments, $args = array('type' => 'pings', 'callback' => 'atom_ping')){
if(empty($comments)) return;
wp_list_comments($args, $comments);
}
/**
* Output the comment navigation
*
* @since 1.2
*
* @param string $classes Extra CSS classes to add to the container div
*/
function atom_comment_navi($classes = ''){
if (atom_get_options('page_comments')) // multiple comment pages
if ($comment_pages = paginate_comments_links('echo=0'))
echo "\n
{$comment_pages}
";
}
/**
* Output the edit/reply/quote comment links
*
* @since 1.2
*/
function atom_comment_controls(){
global $comment;
edit_comment_link(_a('Edit'), '', '');
if (current_user_can('moderate_comments')): // spam/del/approve links ?>
comment_ID}"); ?>">comment_ID}"); ?>">
comment_approved == '0'): // approve link ?>
comment_ID}"); ?>">
add_menu(array('parent' => 'appearance', 'id' => 'atom-settings', 'title' => sprintf(_a('%s settings'), THEME_NAME), 'href' => admin_url('admin.php?page='.ATOM)));
}
/**
* Get the translation of a string
* Uses WP's __() function.
* These functions only exist to make templating easier by omitting the textdomain (ATOM) :)
*
* @since 1.2
*
* @param string $string
*
* @return string Translated string
*/
function _a($string){
return __($string, ATOM);
}
/**
* Output the translation of a string
* Uses WP's _e() function.
*
* @since 1.2
*
* @param string $string
*/
function _ae($string){
_e($string, ATOM);
}
/**
* Get the single/plural form of a string
* Uses WP's _n() function.
*
* @since 1.2
*
* @param string $string
*
* @return string Translated string
*/
function _an($single, $plural, $number){
return _n($single, $plural, $number, ATOM);
}
/**
* Include taxonomies in search, like tags or categories.
* based on: http://projects.jesseheap.com/all-projects/wordpress-plugin-tag-search-in-wordpress-23
* Where query.
*
* @since 1.3
*
* @param string $where
*
* @return string
*/
function atom_search_where($where){
global $wpdb;
if (is_search())
$where .= " OR (t.name LIKE '%".get_search_query()."%' AND {$wpdb->posts}.post_status = 'publish')";
return $where;
}
/**
* Join query
*
* @since 1.3
*
* @param string $join
*
* @return string
*/
function atom_search_join($join){
global $wpdb;
if (is_search())
$join .= " LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id";
return $join;
}
/**
* Group by query
*
* @since 1.3
*
* @param string $join
*
* @return string
*/
function atom_search_groupby($groupby){
global $wpdb;
// we need to group on post ID
$groupby_id = "{$wpdb->posts}.ID";
if(!is_search() || strpos($groupby, $groupby_id) !== false) return $groupby;
// groupby was empty, use ours
if(!strlen(trim($groupby))) return $groupby_id;
// wasn't empty, append ours
return "{$groupby}, {$groupby_id}";
}
/**
* Get the output of a function.
* Useful if someone needs quick control over the output of any function
*
* @since 1.3
*
* @return string
*/
function atom_get(){
$args = func_get_args();
$callback = array_shift($args);
ob_start();
call_user_func_array($callback, $args);
return apply_filters("atom_get_{$callback}", ob_get_clean(), $args);
}
/**
* Number of posts/comments user has written.
* Can count custom post types
*
* @since 1.3
* @uses $wpdb WordPress database object for queries.
*
* @param int $user_id (optional) Count only posts/comments of a user
* @param int $what_to_count Post types or comments, Default is "post"
*
* @return int count
*/
function atom_count($user_id = null, $what_to_count = 'post') {
global $wpdb;
if(strtoupper($user_id) == 'ALL') $user_id = null;
$where = $what_to_count == 'comment' ? "WHERE comment_approved = 1" : get_posts_by_author_sql($what_to_count, TRUE, $user_id);
if(!empty($user_id) && $what_to_count == 'comment') $where .= " AND user_id = {$user_id}";
$from = "FROM ".(($what_to_count == 'comment') ? $wpdb->comments : $wpdb->posts);
return apply_filters("atom_user_{$what_to_count}_count", $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) {$from} {$where}")), $user_id);
}
/**
* AJAX headers
*
* @since 1.3
*
* @param string $nonce
*/
function atom_ajax_header($nonce = '', $content_type = "text/html"){
defined("DOING_AJAX") or define("DOING_AJAX", true);
@header("Content-Type: {$content_type}; charset=".atom_get_options('blog_charset'));
// not really needed, as we only request a list of comments :)
if($nonce) check_ajax_referer("atom_{$nonce}", "_ajax_nonce");
}
/**
* check for AJAX request
*
* @since 1.3
*
* @param string $req
*
* @return bool
*/
function atom_ajax_request($req){
return (isset($_GET['atom']) && ($_GET['atom'] == $req));
}
/**
* Create nonce
*
* @since 1.3
*
* @param string $req
*/
function atom_nonce($req){
echo wp_create_nonce("atom_{$req}");
}
/**
* Removes expired transients from the database
* http://wordpress.stackexchange.com/questions/6602/are-transients-garbage-collected
* This should be integrated in the WP core...
*
* @since `1.3
*/
function atom_delete_expired_transients(){
global $wpdb, $_wp_using_ext_object_cache;
if($_wp_using_ext_object_cache) return;
$time = isset($_SERVER['REQUEST_TIME']) ? (int)$_SERVER['REQUEST_TIME'] : time();
$expired = $wpdb->get_col("SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout%' AND option_value < {$time};");
foreach($expired as $transient):
$key = str_replace('_transient_timeout_', '', $transient);
delete_transient($key);
endforeach;
atom_add_debug_message("Deleted expired transients.");
}
/**
* Check if multisite is enabled and if the current site is the main site
*
* @since 1.3
* @global array $wp_registered_widgets
* @global array $wp_registered_sidebars
*
* @param array|string $args Optional. Override default arguments.
* @return array site list and values
*/
function atom_mu_network(){
global $blog_id;
return (is_multisite() && $blog_id == 1);
}
/**
* Return a list of sites for the current network (replaces old get_blog_list())
* based on http://core.trac.wordpress.org/ticket/14511
*
* @since 1.3
* @global $wpdb
*
* @param array|string $args Optional. Override default arguments.
* @return array site list and values
*/
function atom_get_sites($args = array()){
global $wpdb;
$defaults = array(
'exclude_id' => '', // excludes these sites from the results, comma-delimted
'blogname_like' => '', // domain or path is like this value
'reg_date_since' => '', // sites registered since (accepts pretty much any valid date like tomorrow, today, 5/12/2009, etc.)
'reg_date_before' => '', // sites registered before
'exclude_user_id' => '', // don't include sites owned by these users, comma-delimited
'exclude_archived' => false, // exclude archived sites
'exclude_spam' => false, // exclude spammy sites
'exclude_mature' => false, // exclude blogs marked as mature
'public_only' => true, // Include only blogs marked as public
'sort_column' => 'last_updated', // or registered, last_updated, site_id
'order' => 'ASC', // or desc
'limit_results' => false, // return this many results
'start' => 0, // return results starting with this item
);
// array_merge
$r = wp_parse_args($args, $defaults);
extract($r, EXTR_SKIP);
$query = "SELECT {$wpdb->blogs}.blog_id, {$wpdb->blogs}.domain, {$wpdb->blogs}.path, {$wpdb->blogs}.registered, {$wpdb->blogs}.last_updated, {$wpdb->blogs}.public, {$wpdb->blogs}.archived, {$wpdb->blogs}.mature, {$wpdb->registration_log}.email FROM {$wpdb->blogs}, {$wpdb->registration_log} WHERE site_id = '{$wpdb->siteid}' AND {$wpdb->blogs}.blog_id = {$wpdb->registration_log}.blog_id ";
if(!empty($exclude_id))
$query .= " AND {$wpdb->blogs}.blog_id NOT IN ('".implode("','", explode(',', $exclude_id))."') ";
if(!empty($blogname_like))
$query .= " AND ({$wpdb->blogs}.domain LIKE '%{$blogname_like}%' OR {$wpdb->blogs}.path LIKE '%{$blogname_like}%') ";
if(!empty($reg_date_since))
$query .= " AND unix_timestamp({$wpdb->registration_log}.date_registered) > '".strtotime($reg_date_since)."' ";
if(!empty($reg_date_before))
$query .= " AND unix_timestamp({$wpdb->registration_log}.date_registered) < '".strtotime($reg_date_before)."' ";
if(!empty($exclude_user_id)){
$the_users = explode(',', $exclude_user_id);
$the_emails = array();
foreach((array) $the_users as $user_id){
$the_user = get_userdata($user_id);
$the_emails[] = $the_user->user_email;
}
$list = implode("','", $the_emails);
$query .= " AND {$wpdb->registration_log}.email NOT IN ('{$list}') ";
}
if($public_only) $query .= " AND {$wpdb->blogs}.public = '1'";
if($exclude_archived) $query .= " AND {$wpdb->blogs}.archived = '0'";
if($exclude_spam) $query .= " AND {$wpdb->blogs}.spam = '0'";
if($exclude_mature) $query .= " AND {$wpdb->blogs}.mature = '0'";
if($sort_column == 'id')
$query .= " ORDER BY {$wpdb->blogs}.blog_id ";
elseif($sort_column == 'last_updated')
$query .= " ORDER BY last_updated ";
elseif($sort_column == 'registered')
$query .= " ORDER BY {$wpdb->blogs}.registered ";
$order = ('DESC' == $order) ? "DESC" : "ASC";
$query .= $order;
$limit = '';
if($limit_results){
if($start != 0) $limit = $start.", ";
$query .= " LIMIT ".$limit.$limit_results;
}
return $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
}
/**
* Displays the comment karma controls
*
* @since 1.3
* @global $comment
*
* @param string $classes Optional, extra CSS classes to add to the container
*
* @return bool
*/
function atom_comment_karma($classes = ''){
global $comment;
if(!atom_get_options('comment_karma') || !atom_get_options('jquery')) return; ?>
'.htmlentities("<{$tag}>").''; $commenter = wp_get_current_commenter(); $req = atom_get_options('require_name_email'); $aria_req = ($req ? " aria-required='true'" : ''); $labels = array('author' => _a('Name').($req ? " "._a("(required)") : ''), 'email' => _a('E-mail').($req ? " "._a("(required, will not be published)") : _a("(will not be published)")), 'url' => _a('Website')); $fields = array( 'author' => (!atom_get_options('jquery') ? ' ' : '').'', 'email' => (!atom_get_options('jquery') ? ' ' : '').'', 'url' => (!atom_get_options('jquery') ? ' ' : '').'' ); $defaults = array( 'fields' => apply_filters('comment_form_default_fields', $fields), 'comment_field' => '', 'logged_in_as' => sprintf(_a('Logged in as %s.'), ''.$user_identity.'').' '._a('Log out?').'', 'id_form' => 'commentform', 'id_submit' => 'submit', 'cancel_reply_link' => _a( 'Cancel reply' ), 'label_submit' => _a('Post Comment'), /*/ @todo: find a way to integrate these as well 'title_reply' => __('Leave a Reply'), 'title_reply_to' => __('Leave a Reply to %s'), 'comment_notes_before' => ''.__( 'Your email address will not be published.').($req ? $required_text : '').'
', 'comment_notes_after' => ''.sprintf(__('You may use these HTML tags and attributes: %s'), '
', 'must_log_in' => ''.allowed_tags().'').''. sprintf(__('You must be logged in to post a comment.'), wp_login_url(apply_filters('the_permalink', get_permalink($post_id)))) .'
', //*/ ); $args = wp_parse_args($args, apply_filters('comment_form_defaults', $defaults)); ?>