Skip to content
24 changes: 24 additions & 0 deletions lib/Factory/Factory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Timber\Factory;

/**
* Class Factory
* @package Timber\Factory
*/
abstract class Factory implements FactoryInterface {

protected $object_class = null;

/**
* Factory constructor.
*
* @param string $object_class
*/
function __construct( $object_class = '' ) {
if ( $object_class && class_exists( $object_class ) ) {
$this->object_class = $object_class;
}
}

}
21 changes: 21 additions & 0 deletions lib/Factory/FactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Timber\Factory;

/**
* Interface FactoryInterface
* @package Timber\Factory
*/
interface FactoryInterface {

/**
* @return object
*/
public static function get();

/**
* @return object
*/
public function get_object();

}
61 changes: 61 additions & 0 deletions lib/Factory/ObjectClassFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Timber\Factory;
use Timber\Helper;

/**
* Class ObjectFactoryClass
* @package Timber
*/
class ObjectClassFactory {

public static $TermClass = '\Timber\Term';
public static $PostClass = '\Timber\Post';

/**
* @param string $type The object type: "post" or "term"
* @param string|null $object_type The object's internal type: a post type or taxonomy
* like "portfolio" or "cars")
* @param object|null $object The object for which the class is being retrieved
* @param string|null $class The desired class; overrides results of
* Timber\${type}ClassMap filter
*
* @return mixed|string a PHP class to use for the object
*/
public static function get_class( $type, $object_type = null, $object = null, $class = null ) {

$type = ucwords( $type );

$default_class = static::${"{$type}Class"};
$class_to_use = $class;

if ( is_null($class_to_use) ) {
$class_to_use = $default_class;
}

if ( ! $class_to_use || $class_to_use && ! class_exists( $class_to_use ) ) {

$class_to_use = $default_class;
$class = apply_filters( "Timber\\${type}ClassMap", $class, $object_type, $object, $default_class );

if ( is_string( $class ) ) {
$class_to_use = $class;
} else if ( is_array( $class ) && is_string( $object_type ) ) {
if ( isset( $class[ $object_type ] ) ) {
$class_to_use = $class[ $object_type ];
} else {
Helper::error_log( $object_type . ' not found in ' . print_r( $class, true ) );
}
} else {
Helper::error_log( "Unexpected value for {$type}Class: " . print_r( $class, true ) );
}

}

if ( ! class_exists( $class_to_use ) || ! ( is_subclass_of( $class_to_use, $default_class ) || is_a( $class_to_use, $default_class, true ) ) ) {
Helper::error_log( 'Class ' . $class_to_use . " either does not exist or implement $default_class" );
}
return apply_filters( "Timber\\${type}Class", $class_to_use, $object_type, $object_type, $default_class );
}

}
17 changes: 17 additions & 0 deletions lib/Factory/ObjectGetterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Timber\Factory;

/**
* Interface ObjectGetterInterface
* @package Timber\Factory
*/
interface ObjectGetterInterface {

/**
* @param null $identifier
*
* @return mixed
*/
static function get_object( $identifier );
}
31 changes: 31 additions & 0 deletions lib/Factory/PostFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Timber\Factory;

/**
* Class PostFactory
* @package Timber
*/
class PostFactory extends Factory implements FactoryInterface {

/**
* @param \WP_Post|int|string|null $post_identifier
*
* @return \Timber\Post|null
*/
public static function get( $post_identifier = null ) {
return ( new self() )->get_object( $post_identifier );
}

/**
* @param \WP_Post|int|null $post_identifier
*
* @return \Timber\Post|null
*/
public function get_object( $post_identifier = null ) {
$post = PostGetter::get_object( $post_identifier );
$class = ObjectClassFactory::get_class( 'post', get_post_type( $post ), $post, $this->object_class );

return $post ? new $class( $post ) : null;
}
}
181 changes: 181 additions & 0 deletions lib/Factory/PostGetter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?php

namespace Timber\Factory;

/**
* Class Post
* @package Timber\Factory
*/
class PostGetter implements ObjectGetterInterface {

/**
* @param null $identifier
*
* @return \WP_Post|null
*/
static function get_object( $identifier = null ) {
$identifier = static::determine_id( $identifier );

return $identifier ? static::get_post_from_identifier( $identifier ) : null;
}

/**
* @param $identifier
*
* @return false|int
*/
static function determine_id( $identifier ) {
if ( null === $identifier ) {
return static::determine_id_from_query();
}

return $identifier;
}

/**
* Grabs the global post, from:
* \WP_Query::queried_object_id
*
*
*
* @return false|int
*/
static function determine_id_from_query() {
global $wp_query;
$identifier = null;

if ( isset( $wp_query->queried_object_id )
&& $wp_query->queried_object_id
&& isset( $wp_query->queried_object )
&& is_object( $wp_query->queried_object )
&& get_class( $wp_query->queried_object ) == 'WP_Post'
) {
if ( isset( $_GET[ 'preview' ] ) && isset( $_GET[ 'preview_nonce' ] ) && wp_verify_nonce( $_GET[ 'preview_nonce' ], 'post_preview_' . $wp_query->queried_object_id ) ) {
$identifier = static::get_post_preview_id( $wp_query );
} else if ( ! $identifier ) {
$identifier = $wp_query->queried_object_id;
}
} else if ( $wp_query->is_home && isset( $wp_query->queried_object_id ) && $wp_query->queried_object_id ) {
//hack for static page as home page
$identifier = $wp_query->queried_object_id;
} else {
$identifier = get_the_ID();
if ( ! $identifier ) {
global $wp_query;
if ( isset( $wp_query->query[ 'p' ] ) ) {
$identifier = $wp_query->query[ 'p' ];
}
}
}

if ( $identifier === null && ( $identifier_from_loop = PostGetter::loop_to_id() ) ) {
$identifier = $identifier_from_loop;
}

return $identifier;
}

/**
* @param $query
*
* @return bool|void
*/
protected static function get_post_preview_id( $query ) {
$can = array(
'edit_' . $query->queried_object->post_type . 's',
);

if ( $query->queried_object->author_id !== get_current_user_id() ) {
$can[] = 'edit_others_' . $query->queried_object->post_type . 's';
}

$can_preview = array();

foreach ( $can as $type ) {
if ( current_user_can( $type ) ) {
$can_preview[] = true;
}
}

if ( count( $can_preview ) !== count( $can ) ) {
return false;
}

$revisions = wp_get_post_revisions( $query->queried_object_id );

if ( ! empty( $revisions ) ) {
$revision = reset( $revisions );

return $revision->ID;
}

return false;
}

/**
* takes a mix of integer (post ID), string (post slug),
* or object to return a WordPress post object from WP's built-in get_post() function
* @internal
*
* @param integer|string|object|\WP_Post $identifier
*
* @return \WP_Post|null
*/
protected static function get_post_from_identifier( $identifier = 0 ) {
if ( is_string( $identifier ) || is_numeric( $identifier ) || ( is_object( $identifier ) && ! isset( $identifier->post_title ) ) || $identifier === 0 ) {
$pid = self::check_post_id( $identifier );
$post = get_post( $pid );
return $post;
}

//we can skip if already is WP_Post
return $identifier;
}

/**
* helps you find the post id regardless of whether you send a string or whatever
*
* @param integer $pid ;
*
* @internal
* @return integer|null ID number of a post
*/
protected static function check_post_id( $pid ) {
if ( is_numeric( $pid ) && $pid === 0 ) {
$pid = get_the_ID();

return $pid;
}
if ( ! is_numeric( $pid ) && is_string( $pid ) ) {
$pid = self::get_post_id_by_name( $pid );

return $pid;
}
if ( ! $pid ) {
return null;
}

return $pid;
}

/**
* get_post_id_by_name($post_name)
* @internal
*
* @param string $post_name
*
* @return int
*/
public static function get_post_id_by_name( $post_name ) {
global $wpdb;
$query = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name );
$result = $wpdb->get_row( $query );
if ( ! $result ) {
return null;
}

return $result->ID;
}


}
37 changes: 37 additions & 0 deletions lib/Factory/TermFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Timber\Factory;

/**
* Class Term
* @package Timber\Factory
*/
class TermFactory extends Factory implements FactoryInterface {


/**
* @param \WP_Term|int|string|null $term $term
* @param string $taxonomy
* @param string $field
*
* @return \Timber\Term
*/
public static function get( $term = null, $taxonomy = 'category', $field = 'term_taxonomy_id' ) {
return ( new self() )->get_object( $term, $taxonomy, $field );
}

/**
* @param \WP_Term|int|string|null $term
*
*
* @return \Timber\Term
*/
public function get_object( $term = null, $taxonomy = 'category', $field = 'term_taxonomy_id' ) {
$term = TermGetter::get_object( $term, $taxonomy, $field );

$class = ObjectClassFactory::get_class( 'term', $term->taxonomy, $term, $this->object_class );

return $term ? new $class( $term ) : null;
}

}
Loading