Skip to content

Instantly share code, notes, and snippets.

@dnaber-de
Created October 1, 2013 10:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dnaber-de/6776294 to your computer and use it in GitHub Desktop.
Save dnaber-de/6776294 to your computer and use it in GitHub Desktop.
Example of a class reflection to make the availability of this class optional.
<?php
/**
* base reflector class to reflect plugins APIs without using
* plugin classes directly
*
*/
namespace Project\Theme\Reflector;
abstract class Class_Reflector {
/**
* the name of the reflected class
*
* @var string
*/
protected $class = '';
/**
* reference of the the object to reflect
*
* @var Instance of $class
*/
protected $object = NULL;
/**
* reflector of the object
*
* @var ReflectionObject
*/
protected $reflector_object = NULL;
/**
* gets the global $wpdb
*
* @param string $class Class to reflect
* @param mixed (passed to the constructor)
* @return DB
*/
public function __construct( $class ) {
$args = array_reverse( func_get_args() );
array_pop( $args );
$args = array_reverse( $args );
try {
$this->reflector_object = new \ReflectionClass( $class );
$this->object = $this->reflector_object->newInstanceArgs( $args );
} catch( \ReflectionException $e ) {
$error_level = \E_USER_NOTICE;
if ( defined( '\WP_DEBUG' ) && \WP_DEBUG )
$error_level = \E_USER_WARNING;
$this->trigger_error( $e->getMessage(), $error_level );
}
}
/**
* call methods of the object
*
* @param string $method
* @param array $args
* @return mixed
*/
public function __call( $name, $args = array() ) {
if ( ! $this->object )
return;
$methods = $this->reflector_object->getMethods();
foreach ( $methods as $m ) {
if ( $name !== $m->getName() )
continue;
if ( $m->isPrivate() )
return $this->trigger_error( 'Access to private method "' . $name . '" of ' . $this->class, \E_USER_ERROR );
if ( $m->isProtected() )
return $this->trigger_error( 'Access to protected method "' . $name . '" of ' . $this->class, \E_USER_ERROR );
return $m->invokeArgs( $this->object, $args );
}
return $this->trigger_error( 'Called to undefined method "' . $name . '" of ' . $this->class, \E_USER_ERROR );
}
/**
* get property of wpdb
*
* @param string $name
* @return mixed
*/
public function __get( $name ) {
if ( ! $this->object )
return;
$prop = $this->reflector_object->getProperties();
foreach ( $prop as $p ) {
if ( $name !== $p->getName() )
continue;
if ( $p->isPrivate() )
return $this->trigger_error( 'Access to private property "' . $name . '" of ' . $this->class, \E_USER_ERROR );
if ( $p->isProtected() )
return $this->trigger_error( 'Access to protected property "' . $name . '" of ' . $this->class, \E_USER_ERROR );
return $p->getValue( $this->object );
}
return $this->trigger_error( 'Access to undefined property "' . $name . '" of ' . $this->class, \E_USER_ERROR );
}
/**
* set property of wpdb
*
* @param string $name
* @param mixed $value
* @return void
*/
public function __set( $name, $value = NULL ) {
if ( ! $this->object )
return;
$prop = $this->reflector_object->getProperties();
foreach ( $prop as $p ) {
if ( $name !== $p->getName() )
continue;
if ( $p->isPrivate() )
return $this->trigger_error( 'Access to private property "' . $name . '" of ' . $this->class, \E_USER_ERROR );
if ( $p->isProtected() )
return $this->trigger_error( 'Access to protected property "' . $name . '" of ' . $this->class, \E_USER_ERROR );
return $p->setValue( $this->object, $value );
}
$this->object->{ $name } = $value;
}
/**
* trigger a native php error
*
* @param string $msg
* @param int $error_type
* @return void
*/
public function trigger_error( $msg, $error_type ) {
$backtrace = \debug_backtrace();
$callee = $backtrace[ 0 ];
$msg .= ' in <strong>' . $callee[ 'file' ] . '</strong> on line <strong>' . $callee[ 'line' ] . '</strong>';
\trigger_error( $msg, $error_type );
}
}
<?php
/**
* reflector of Project\Plugin\Data_Model
*/
namespace Project\Theme\Reflector;
class Plugin_Model extends Class_Reflector {
/**
* constructor
*
* @see Project\Plugin\Data_Model
* @param mixed
* @return Project\Theme\Reflector\Plugin_Model
*/
public function __construct() {
$args = array( '\Project\Plugin\Data_Model' );
$args = array_merge( $args, func_get_args() );
return call_user_func_array( array( $this, 'parent::__construct' ), $args );
}
}
<?php
/**
* example usage in the theme
*/
namespace Project\Theme;
$plugin_model = new Reflector\Plugin_Model( $some, $args );
# if the plugin is active
$data = $plugin_model->get_cool_data(); // gets the expected results
# if the plugin is deactivated
# if WP_DEBUG
$data = $plugin_model->get_cool_data(); // NULL, Produces a E_WARNING
# else
$data = $plugin_model->get_cool_data(); // NULL, Produces a Notice
@dnaber-de
Copy link
Author

Published this, before logged in here: https://gist.github.com/anonymous/6776250

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment