'f5f5f5',
'border' => 'dddddd',
'text' => '555555',
'link' => '21759b'
);
}
$content_width = 488; // pixels
/**
* Register some dependencies at initialisation.
*
* @return void
**/
function pp_init()
{
wp_register_script( 'pp-front', get_bloginfo('template_url') . '/prologue-projects.js', false, '20090218' );
wp_register_style( 'pp-reset-fonts', get_bloginfo('template_url') . '/reset-fonts.css', false, '20090218' );
wp_register_style( 'pp-front', get_bloginfo('template_url') . '/style.css', array('pp-reset-fonts'), '20090218' );
}
add_action( 'init', 'pp_init' );
/**
* Enqueue our dependencies for linking in the html head.
*
* @return void
**/
function pp_head()
{
wp_enqueue_script( 'pp-front' );
wp_enqueue_style( 'pp-front' );
}
add_action( 'wp_head', 'pp_head', 1 );
/**
* Where the bloody hell are ya?
*
* @return string The current URL.
**/
function pp_get_current_url()
{
$schema = is_ssl() ? 'https://' : 'http://';
return $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
/**
* Get stored options for prologue_projects and merge them with the defaults.
*
* @return array All the options.
**/
function pp_get_options()
{
$defaults = array(
'category_projects' => false,
'featured_project' => false,
'project_data' => array(),
'projects_sidebars' => false,
'category_updates' => false,
'category_tasks' => false,
'default_task_level' => false,
'category_questions' => false,
'default_question_state' => false,
'author_sidebars' => false
);
$options = get_option( 'prologue_projects' );
return array_merge( $defaults, $options );
}
/**
* Get a single prologue_projects option
*
* @param string $key The key of the option to be retrieved.
* @return mixed The value of the option or boolean false if not set.
**/
function pp_get_option( $key )
{
if ( !$key ) {
return false;
}
$options = pp_get_options();
if ( !isset( $options[$key] ) ) {
return false;
}
return $options[$key];
}
/**
* Shorthand function to retrieve the actual category id of a prologue_projects post type
*
* @param string $type The post type whose category id is to be returned, can be one of "projects", "updates", "tasks" or "questions".
* @return int The category id or false if none is set.
**/
function pp_get_category_id( $type )
{
return pp_get_option( 'category_' . $type );
}
/**
* Allows for template customisation of individual projects by injecting new files named after the project slug into the template hierarchy.
*
* When a request is made for "updates" in the project "foo", WordPress will look for the following files in order:
* 1. updates-foo.php
* 2. updates.php
* 3. index.php
* 4. The originally determined category template, passed as parameter $template.
*
* @param string $template The originally determined category template.
* @return void
**/
function pp_category_template( $template )
{
$requested_category_id = absint( get_query_var( 'cat' ) );
$types = array(
'projects' => pp_get_category_id( 'projects' ),
'updates' => pp_get_category_id( 'updates' ),
'tasks' => pp_get_category_id( 'tasks' ),
'questions' => pp_get_category_id( 'questions' )
);
foreach ( $types as $_type => $_category_id ) {
if ( !$_category_id ) {
continue;
}
$_category = get_category( absint( $_category_id ) );
if ( !$_category || is_wp_error( $_category ) ) {
continue;
}
if ( $_category_id == $requested_category_id ) {
return locate_template( array(
$_type . '.php',
'index.php',
$template
) );
}
$_ids = get_categories( array(
'child_of' => $_category_id,
'hide_empty' => false,
'fields' => 'ids'
) );
if ( !in_array( $requested_category_id, $_ids ) ) {
continue;
}
$_type_category = get_category( $requested_category_id );
if ( !$_type_category || is_wp_error( $_type_category ) ) {
continue;
}
return locate_template( array(
$_type . '-' . $_type_category->slug . '.php',
$_type . '.php',
'index.php',
$template
) );
}
return $template;
}
add_filter( 'category_template', 'pp_category_template' );
/**
* Allows the use of Trac-style shorthand for links to Trac tickets and changesets.
*
* @param string $text The text to be modified.
* @return string The modified text.
**/
function pp_make_tracable( $text )
{
if ( !$text || !preg_match( '@(?:#[a-z0-9]+)|(?:\[[a-z0-9]+\])@i', $text ) ) {
return $text;
}
global $id, $post;
if ( !$category_ids = wp_get_post_categories( $id ) ) {
return $text;
}
$project_tracs = array();
$i = 0;
foreach ( $category_ids as $category_id ) {
$project_data = pp_get_project_data( $category_id );
if ( isset( $project_data['trac'] ) && $project_data['trac'] ) {
$i++;
$project_tracs[$i][0][0] = '#' . preg_quote( $project_data['slug'] ) . '([0-9]+)';
$project_tracs[$i][0][1] = $project_data['trac'] . 'ticket/$1';
$project_tracs[$i][0][2] = '#' . $project_data['slug'] . '$1';
$project_tracs[$i][1][0] = '\[' . preg_quote( $project_data['slug'] ) . '([0-9]+)\]';
$project_tracs[$i][1][1] = $project_data['trac'] . 'changeset/$1';
$project_tracs[$i][1][2] = '[' . $project_data['slug'] . '$1]';
if ( isset( $project_data['intertrac'] ) && $project_data['intertrac'] ) {
$project_tracs[$i][2][0] = '#' . preg_quote( $project_data['intertrac'] ) . '([0-9]+)';
$project_tracs[$i][2][1] = $project_data['trac'] . 'ticket/$1';
$project_tracs[$i][2][2] = '#' . $project_data['intertrac'] . '$1';
$project_tracs[$i][3][0] = '\[' . preg_quote( $project_data['intertrac'] ) . '([0-9]+)\]';
$project_tracs[$i][3][1] = $project_data['trac'] . 'changeset/$1';
$project_tracs[$i][3][2] = '[' . $project_data['intertrac'] . '$1]';
}
}
}
if ( !count( $project_tracs ) ) {
return $text;
}
if ( count( $project_tracs ) === 1 ) {
$project_tracs[0][0][0] = '#([0-9]+)';
$project_tracs[0][0][1] = $project_tracs[1][0][1];
$project_tracs[0][0][2] = '#$1';
$project_tracs[0][1][0] = '\[([0-9]+)\]';
$project_tracs[0][1][1] = $project_tracs[1][1][1];
$project_tracs[0][1][2] = '[$1]';
}
ksort( $project_tracs );
foreach ( $project_tracs as $pairs ) {
foreach ( $pairs as $pair ) {
$text = preg_replace( '@' . $pair[0] . '@', '' . $pair[2] . '', $text );
}
}
return $text;
}
add_filter( 'the_content', 'pp_make_tracable', 1 );
add_filter( 'the_content', 'make_clickable' );
/**
* Get the meta data of a given project.
*
* @param integer $category_id The category id of the project.
* @param string $type Optional. The specific meta data to get. Default is "all", which retrieves all meta data.
* @return mixed The projects meta data in an associative array or the specific data as requested with the $type parameter.
**/
function pp_get_project_data( $category_id = 0, $type = 'all', $context = '' )
{
if ( !$category_id ) {
global $cat;
$category_id = $cat;
}
if ( !$category_id ) {
return false;
}
if ( is_object( $category_id ) && !is_wp_error( $category_id ) ) {
$category = $category_id;
$category_id = $category->cat_ID;
}
if ( !$context && $cache = wp_cache_get( $category_id, 'pp_project_data' ) ) {
if ( 'all' === $type ) {
return $cache;
}
if ( !isset( $cache[$type] ) ) {
return false;
}
return $cache[$type];
}
if ( !isset( $category ) ) {
$category = get_category( $category_id );
}
if ( !$category || is_wp_error( $category ) ) {
return false;
}
$data = array();
$data['id'] = $category->cat_ID;
$data['name'] = $category->name;
$data['parent_id'] = $category->parent;
$data['slug'] = $category->slug;
$data['url'] = get_category_link( $category->cat_ID );
$data['link'] = '' . $data['name'] . '';
$data['description'] = $category->description;
$data['logo'] = '';
$data['website'] = '';
$data['blog'] = '';
$data['svn'] = '';
$data['trac'] = '';
$data['intertrac'] = '';
$data['activity'] = array();
$data['overheard'] = array();
if ( $meta = get_option( 'pp_project_meta_' . $data['id'] ) ) {
foreach ( $meta as $key => $value ) {
if ( in_array( $key, array( 'intertrac', 'logo' ) ) ) {
$data[$key] = $value;
} elseif ( in_array( $key, array( 'activity', 'overheard' ) ) && $value ) {
$data[$key] = array_merge( $data[$key], $value );
} elseif ( $value ) {
$data[$key] = rtrim( $value, '/' ) . '/';
}
}
if ( $data['trac'] && !$context ) {
$data['activity'][] = $data['trac'] . 'timeline?milestone=on&ticket=on&changeset=on&wiki=on&format=rss&max=20';
}
}
if ( !$context ) {
wp_cache_add( $category_id, $data, 'pp_project_data' );
}
if ( 'all' === $type ) {
return $data;
}
if ( !isset( $data[$type] ) ) {
return false;
}
return $data[$type];
}
/**
* Callback to clean out the specific project data cache when categories are edited.
*
* @param $category_id The category id of the project.
* @return boolean True if the cache was emptied.
**/
function pp_delete_project_data_cache( $category_id )
{
if ( !$category_id ) {
return false;
}
return wp_cache_delete( $category_id, 'pp_project_data' );
}
add_action( 'delete_category', 'pp_delete_project_data_cache', 10, 1 );
add_action( 'edit_category', 'pp_delete_project_data_cache', 10, 1 );
/**
* Find out if the given category is a project.
*
* @param integer $category_id The id of the category.
* @return boolean True if it is a project, otherwise false.
**/
function pp_is_project( $category_id = 0 )
{
$categories = pp_get_projects();
if ( !$categories || ! is_countable( $categories ) || count( $categories ) < 1 ) {
return false;
}
if ( !$category_id = pp_get_project_data( $category_id, 'id' ) ) {
return false;
}
$is_project = false;
foreach ( $categories as $category ) {
if ( $category_id == $category->cat_ID ) {
$is_project = true;
break;
}
}
return $is_project;
}
function pp_get_projects( $parent_id = 0 )
{
if ( $parent_id && !pp_is_project( $parent_id ) ) { // Narrowly avoiding circular logic here :)
return;
} elseif ( !$parent_id && !$parent_id = pp_get_category_id( 'projects' ) ) {
return;
}
$categories = get_categories( array(
'child_of' => $parent_id,
'hierarchical' => 1,
'hide_empty' => 0
) );
return $categories;
}
function pp_get_question_statuses()
{
if ( !$parent_id = pp_get_category_id( 'questions' ) ) {
return;
}
$categories = get_categories( array(
'child_of' => $parent_id,
'hide_empty' => 0
) );
return $categories;
}
function pp_is_question_status( $category_id )
{
if ( !$category_id ) {
return false;
}
$categories = pp_get_question_statuses();
if ( !$categories || ! is_countable( $categories ) || count( $categories ) < 1 ) {
return false;
}
$is_status = false;
foreach ( $categories as $category ) {
if ( $category_id == $category->cat_ID ) {
$is_status = true;
break;
}
}
return $is_status;
}
function pp_get_project_members( $category_id = 0 )
{
$project_id = pp_get_project_data( $category_id, 'id' );
if ( !$project_id ) {
return false;
}
global $wpdb, $blog_id;
$query = "SELECT `user_id`, `user_login`, `user_nicename`, `display_name`, `user_email`, `meta_value`
FROM `" . $wpdb->users . "`, `" . $wpdb->usermeta . "`
WHERE `" . $wpdb->users . "`.`ID` = `" . $wpdb->usermeta . "`.`user_id`
AND `meta_key` = 'prologue_projects_" . $blog_id . "'
AND `meta_value` LIKE '%i:" . (int) $project_id . ";a:2:{i:0;i:1;%'
ORDER BY `" . $wpdb->users . "`.`display_name`;";
$members = $wpdb->get_results( $query, ARRAY_A );
$_members = array();
if ( $members && is_countable( $members ) && count( $members ) ) {
foreach ( $members as $member ) {
$_member = $member;
$_member['projects'] = maybe_unserialize( $member['meta_value'] );
unset( $_member['meta_value'] );
$_member['project_role'] = strip_tags( trim( wp_filter_kses( wp_specialchars( $_member['projects'][$category_id][1] ) ) ) );
unset( $_member['projects'] );
$_members[] = $_member;
}
}
return $_members;
}
function pp_get_user_projects( $user_id = 0 )
{
if ( !$user = new WP_User( $user_id ) ) {
return false;
}
global $blog_id;
$meta = 'prologue_projects_' . $blog_id;
if ( !isset( $user->$meta ) || !$user->$meta || !is_array( $user->$meta ) ) {
return false;
}
$projects = array();
foreach ( $user->$meta as $project_id => $project_settings ) {
if ( $project_settings[0] ) {
$projects[$project_id] = $project_settings[1];
}
}
if ( !count( $projects ) ) {
return false;
}
return $projects;
}
/* Template */
function pp_all_projects_rss()
{
if ( !$url = get_feed_link() ) {
return;
}
$r = '';
$r .= __( 'RSS', 'prologue-projects' );
$r .= '';
echo $r;
}
function pp_project_rss( $category_id = 0 )
{
$data = []; // $data['slug'] below is possibly a bug; adding this init to fix rector.
if ( !$category_id = pp_get_project_data( $category_id, 'id' ) ) {
return;
}
if ( !$url = get_category_feed_link( $category_id ) ) {
return;
}
$r = '';
$r .= __( 'RSS', 'prologue-projects' );
$r .= '';
echo $r;
}
function pp_project_logo( $category_id = 0 )
{
if ( !$data = pp_get_project_data( $category_id ) ) {
return;
}
if ( !isset( $data['logo'] ) || !$data['logo'] ) {
return;
}
if ( !parse_url( $data['logo'] ) ) {
return;
}
$r = '';
echo $r;
}
function pp_project_links( $category_id = 0 )
{
if ( !$data = pp_get_project_data( $category_id ) ) {
return;
}
$r = '