Created
March 17, 2011 19:04
-
-
Save felipelavinz/874920 to your computer and use it in GitHub Desktop.
Abstract class for dealing with common tasks over WordPress post objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Basically, a posts objects iterator | |
* @author Felipe Lavín Z. <[email protected]> | |
**/ | |
abstract class av_post_objects{ | |
public $id; | |
public $meta; | |
public $type; | |
public $i = 0; | |
public $params; | |
public $query; | |
function __construct($args=null){ | |
$s = wp_parse_args($args, array( | |
'loop_wrap' => 'div', | |
'loop_class' => '', | |
'loop_id' => '', | |
'loop_elements' => 'div', | |
'elements_class' => '', | |
'is_hatom' => false, // if set to true, add hatom classes | |
'postmeta' => false, // name of a post_meta key that would be used in each post | |
'echo' => true | |
)); | |
$s = array_merge($s, $this->defaults); | |
$this->params = (object)$s; | |
$this->id = get_class($this); | |
} | |
/** | |
* Register post type | |
**/ | |
abstract function register_type(); | |
/** | |
* Get post objects | |
* @param array $args Array or query string of arguments | |
* @return object WP_Query object | |
**/ | |
function get($args=null){ | |
$s = wp_parse_args( (array)$args, (array)$this->params ); | |
// set this to a class variable, so we can have access to the WP_Query properties | |
$this->query = new WP_Query( $s ); | |
return $this->query; | |
} | |
/** | |
* The "view" method should be implemented by each extending class | |
* Format item output for each of the query results | |
* @param $post A $post object | |
* @args $args | |
* @return string Item output | |
**/ | |
abstract function view($post=null, $args=null); | |
/** | |
* Loop should handle all objects retrieving and looping | |
* and let the view method handle the display of each item | |
* Class constructors can define the wrapping and other presentational | |
* attributes that should be applied on the loop | |
**/ | |
function loop($objects=null, $view=null){ | |
global $post; | |
$the_post = $post; | |
if ( !$objects ) $objects = $this->get(); | |
$out = ''; | |
if ( $objects->have_posts() ) { | |
apply_filters('pre_'. $this->id .'_loop', &$out, $objects); | |
$out .= '<'. $this->params->loop_wrap . $this->get_wrap_classes($this->params->loop_class) . (( $this->params->loop_id ) ?' id="'. esc_attr($this->params->loop_id) .'"' : '' ) .'>'; | |
// here there should be a variable-name action, passing $objects as argument | |
// do_action ... | |
apply_filters('start_'. $this->id .'_loop', &$out, $objects); | |
while ( $objects->have_posts() ) { | |
$objects->the_post(); $this->meta = null; | |
$this->meta = $this->get_meta($post); | |
// here there should be a variable-name action, passing the post as argument | |
// do_action... | |
// perhaps this should be captured in an output buffer, just to make sure | |
// that the view action it's not echoing, instead of returning | |
$out .= '<'. $this->params->loop_elements . $this->get_item_classes($this->params->item_class) .' id="'. esc_attr($post->post_name) .'">'; | |
$out .= !is_null($view) && is_callable($view) ? call_user_func($view) : $this->view(); | |
$out .= '</'. $this->params->loop_elements .'>'; | |
$this->i++; | |
} | |
apply_filters('end_'. $this->id .'_loop', &$out, $objects); | |
$out .= '</'. $this->params->loop_wrap .'>'; | |
apply_filters('post_'. $this->id .'_loop', &$out, $objects); | |
wp_reset_query(); | |
$post = $the_post; | |
// here there shoud be a variable-name action, so we can do stuff such as removing query filters | |
} else { | |
$out .= '<p>'. __('No posts have been found') .'</p>'; | |
} | |
if ( $this->params->echo ) echo $out; | |
else return $out; | |
} | |
public function get_meta($post=null){ | |
if ( is_null($post) ) global $post; | |
if ( $this->params->postmeta ) { | |
if ( is_string($this->params->postmeta) ) { | |
$meta = get_post_meta($post->ID, $this->params->postmeta, true); | |
$this->meta = $post->meta = $meta ? $meta : null; | |
} elseif ( is_array($this->params->postmeta) ) { | |
$this->meta = $post->meta = $this->get_meta_arr(); | |
} | |
} | |
} | |
/** | |
* Fetch various meta fields and set them to $this->meta so we can access | |
* them in the posts loop | |
* @param array $metas List of meta keys to fetch | |
* @return array Associative array with meta keys as keys and values as values | |
**/ | |
public function get_meta_arr( $metas = null ){ | |
global $wpdb, $post; $out = new stdClass; | |
if ( is_null($metas) ) $metas = $this->params->postmeta; | |
// If metas is an associative array, we'll use our custom names as keys | |
if ( $this->is_associative($metas) ) { | |
$assoc = true; | |
$names2keys = array_flip($metas); | |
} | |
// Prepare meta keys for query | |
array_walk($metas, array($this, 'prepare_meta_keys')); | |
(array)$meta_values = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id = $post->ID AND meta_key IN(". implode(',', (array)$metas) .")"); | |
if ( $assoc ) { | |
$out = $this->map_meta_keys($meta_values, $names2keys); | |
} else { | |
foreach ( $meta_values as $m ) { | |
$out->{$m->meta_key} = maybe_unserialize($m->meta_value); | |
} | |
} | |
return $out; | |
} | |
/** | |
* Map meta_keys and meta_values to our custom meta names | |
* @param array $values DDBB Query results | |
* @param array $names2keys Associative array with meta keys as keys and our custom names as values | |
* @return array Associative array with custom keys | |
**/ | |
private function map_meta_keys($values, $names2keys){ | |
$out = new stdClass; | |
foreach ( $values as $v ) { | |
$out->$names2keys[$v->meta_key] = maybe_unserialize($v->meta_value); | |
} | |
return $out; | |
} | |
/** | |
* Add slashes to array keys so they won't be mistaken for columns | |
* @param arr $key The array that's checked | |
* @return void Return by reference | |
* */ | |
private function prepare_meta_keys(&$key){ | |
$key = "'$key'"; | |
} | |
/** | |
* Check if it's an associative array | |
* @param array $arr The array that will be tested | |
* @return boolean True if assocative, false if numeric | |
* */ | |
private function is_associative($arr){ | |
return !ctype_digit( implode('', array_keys($arr)) ); | |
} | |
public function get_item_classes($custom=null){ | |
$out = ' class="'. $this->params->post_type .'-entry'; | |
$out .= ( $this->i%2 ) ? ' odd' : ' even'; | |
if ( $this->i === 0 ) $out .= ' first'; | |
if ( $this->i === ( $this->query->found_posts - 1 ) ) $out .= ' last'; | |
if ( $custom ) $out .= ' '. esc_attr($custom); | |
if ( $this->params->hatom ) $out .= ' hentry'; | |
$out .= '"'; | |
return $out; | |
} | |
public function get_wrap_classes($custom=null){ | |
$out = ' class="'. $this->params->post_type .'-loop'; | |
if ( $custom ) $out .= ' '. esc_attr($custom); | |
if ( $this->params->hatom ) $out .= ' hfeed'; | |
$out .= '"'; | |
return $out; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment