Skip to content

Instantly share code, notes, and snippets.

@RadoslavGeorgiev
Last active September 18, 2017 21:41
Show Gist options
  • Save RadoslavGeorgiev/0247993ca18f47e70dde9f0086f1e5f4 to your computer and use it in GitHub Desktop.
Save RadoslavGeorgiev/0247993ca18f47e70dde9f0086f1e5f4 to your computer and use it in GitHub Desktop.
Converting collections to query buidlers in Rila
<?php
class Collection {
protected $item_type = 'Rila\\Item';
public $args;
protected $ids;
public function __construct( $request = null ) {
if( is_null( $request ) ) {
# Allow simple initialization of child classes
if( method_exists( $this, 'initialize' ) ) {
$this->initialize();
}
return;
}
if( is_array( $request ) ) {
$items_only = true;
$ids_only = true;
$ids = array();
$k = 0;
foreach( $request as $i => $item ) {
if( ! is_object( $item ) ) {
$items_only = false;
}
if( ( $i !== $k ) || ! is_scalar( $item ) || ! intval( $item ) ) {
$ids_only = false;
} else {
$ids[] = intval( $item );
}
$k++;
}
if( $ids_only ) {
$this->ids = $ids;
} elseif( $items_only ) {
$this->items = array();
foreach( $request as $item ) {
$this->items[] = call_user_func( array( $this->item_type, 'factory' ), $item );
}
$this->initialized = true;
} else {
$this->args = $request;
}
} else {
$this->args = wp_parse_args( $request );
}
# Allow simple initialization of child classes
if( method_exists( $this, 'initialize' ) ) {
$this->initialize();
}
}
protected function load() {
$msg = "Generic collections cannot load from the database and can only be used with explicit data.";
throw new \Exception( $msg );
}
public function where( $key, $value = null ) {
if( $this->initialized ) {
throw new \Exception( "Once a collection is initialized with data, it cannot be filtered from the database. Use ->filter() instead!" );
}
if( $value ) {
$request = array( $key => $value );
} else {
$request = $key;
}
foreach( $request as $key => $value ) {
$this->set( $key, $value );
$method_name = 'set_' . $key;
}
return $this;
}
protected function set( $key, $value ) {
$this->args[ $key ] = $value;
}
public function filter( $filters ) {
if( ! $this->initialized ) {
$this->load();
}
$filtered = array();
foreach( $this->items as $item ) {
$ok = true;
foreach( $filters as $key => $value ) {
if( $item->raw( $key ) != $value ) {
$ok = false;
break;
}
}
if( $ok ) {
$filtered[] = $item;
}
}
if( empty( $filtered ) ) {
return array();
}
$class_name = get_class( $this );
return new $class_name( $filtered );
}
}
<?php
class Collection {
protected $item_type = 'Rila\\Item';
public $args;
protected $ids;
public function __construct( $request = null ) {
if( is_null( $request ) ) {
# Allow simple initialization of child classes
if( method_exists( $this, 'initialize' ) ) {
$this->initialize();
}
return;
}
if( is_array( $request ) ) {
$items_only = true;
$ids_only = true;
$ids = array();
$k = 0;
foreach( $request as $i => $item ) {
if( ! is_object( $item ) ) {
$items_only = false;
}
if( ( $i !== $k ) || ! is_scalar( $item ) || ! intval( $item ) ) {
$ids_only = false;
} else {
$ids[] = intval( $item );
}
$k++;
}
if( $ids_only ) {
$this->ids = $ids;
} elseif( $items_only ) {
$this->items = array();
foreach( $request as $item ) {
$this->items[] = call_user_func( array( $this->item_type, 'factory' ), $item );
}
$this->initialized = true;
} else {
$this->args = $request;
}
} else {
$this->args = wp_parse_args( $request );
}
# Allow simple initialization of child classes
if( method_exists( $this, 'initialize' ) ) {
$this->initialize();
}
}
protected function load() {
$msg = "Generic collections cannot load from the database and can only be used with explicit data.";
throw new \Exception( $msg );
}
public function where( $key, $value = null ) {
if( $this->initialized ) {
throw new \Exception( "Once a collection is initialized with data, it cannot be filtered from the database. Use ->filter() instead!" );
}
if( $value ) {
$request = array( $key => $value );
} else {
$request = $key;
}
foreach( $request as $key => $value ) {
$this->set( $key, $value );
$method_name = 'set_' . $key;
}
return $this;
}
protected function set( $key, $value ) {
$this->args[ $key ] = $value;
}
public function filter( $filters ) {
$collection = $this->get();
foreach( $filters as $key => $value ) {
$collection = $collection->where( $key, $value );
}
return $collection;
}
}
<?php
abstract class Query_Builder {
protected $item_type = 'Rila\\Item';
public $args;
protected $ids;
protected $items;
public function __construct( $request = null ) {
// If there is no request, `initialize` will directly load defaults.
if( is_null( $request ) ) {
return $this->maybe_initialize();
}
// Convert the request to an array, if a string is given (ex. posts_per_page=1&order=asc).
if( is_string( $request ) ) {
$request = wp_parse_args( $request );
}
// Check if the request is an array, which only contains IDs.
$ids_only = true;
$linear_index = 0;
foreach( $request as $internal_index => $element ) {
if(
$linear_index != $internal_index // Normal arrays should have proper indexes.
|| ! is_scalar( $element ) // IDs are always scalar
|| ! intval( $element ) // and can be converted to a positive integer.
) {
$ids_only = false;
break;
}
$linear_index++;
}
// Once confirmed, save the IDs as an indication of the `ids_only` mode and bail.
if( $ids_only ) {
$this->ids = array_map( 'intval', $request );
return $this->maybe_initialize();
}
// Check if maybe the items are already loaded from the database
$items_only = true;
foreach( $request as $item ) {
if( ! is_object( $Item ) ) {
$items_only = false;
break;
}
}
// Should we just convert to a collection at this point ???
if( $items_only ) {
$this->items = $request;
return $this->maybe_initialize();
}
// At this point, we can only have normal arguments
$this->args = $request;
$this->maybe_initialize();
}
/**
* Checks if there is an `initialize` method and calls it.
*/
protected function maybe_initialize() {
if( method_exists( $this, 'initialize' ) ) {
$this->initialize();
}
}
protected function load() {
$msg = "Generic collections cannot load from the database and can only be used with explicit data.";
throw new \Exception( $msg );
}
public function where( $key, $value = null ) {
if( $this->initialized ) {
throw new \Exception( "Once a collection is initialized with data, it cannot be filtered from the database. Use ->filter() instead!" );
}
if( $value ) {
$request = array( $key => $value );
} else {
$request = $key;
}
foreach( $request as $key => $value ) {
$this->set( $key, $value );
}
return $this;
}
protected function set( $key, $value ) {
$this->args[ $key ] = $value;
return $this;
}
public function filter( $filters ) {
$collection = $this->get();
foreach( $filters as $key => $value ) {
$collection = $collection->where( $key, $value );
}
return $collection;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment