starting Category field type

This commit is contained in:
Leo Germani 2018-03-03 21:22:15 -03:00
parent 78ede584c0
commit e69f003de7
8 changed files with 330 additions and 25 deletions

View File

@ -377,7 +377,7 @@ class Field extends Entity {
return true;
if (!is_array($is_valid))
throw new Exception("Return of validate_options field type method should be an Array in case of error");
throw new \Exception("Return of validate_options field type method should be an Array in case of error");
foreach ($is_valid as $field => $message) {
$this->add_error($field, $message);

View File

@ -0,0 +1,111 @@
<?php
namespace Tainacan\Field_Types;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class TainacanFieldType
*/
class Category extends Field_Type {
function __construct(){
// call field type constructor
parent::__construct();
parent::set_primitive_type('term');
$this->set_default_options([
'allow_new_terms' => false
]);
// TODO: Set component depending on options. If multiple is checkbox. if single, select. etc.
$this->component = 'tainacan-category';
}
/**
* @param $itemMetadata \Tainacan\Entities\Item_Metadata_Entity The instace of the entity itemMetadata
* @return string
*/
public function render( $itemMetadata ){
$options = ( isset( $this->options['options'] ) ) ? $this->options['options'] : '';
return '<tainacan-selectbox
options="' . $options . '"
field_id ="'.$itemMetadata->get_field()->get_id().'"
item_id="'.$itemMetadata->get_item()->get_id().'"
value=\''.json_encode( $itemMetadata->get_value() ).'\'
name="'.$itemMetadata->get_field()->get_name().'"></tainacan-selectbox>';
}
/**
* generate the fields for this field type
*/
public function form(){
global $Tainacan_Taxonomies;
$taxonomies = $Tainacan_Taxonomies->fetch([], 'OBJECT')
// TODO: form incomplete and not tested
?>
<tr>
<td>
<label><?php echo __('Category','tainacan'); ?></label><br/>
<small><?php echo __('Select the category','tainacan'); ?></small>
</td>
<td>
<select name="taxonomy_id">
<?php foreach ($taxonomies as $tax): ?>
<option value="<?php echo $tax->get_db_identifier(); ?>" <?php selected($this->get_option('taxonomy_id'), $tax->get_db_identifier()); ?> ><?php echo $tax->get_name(); ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
<?php
}
public function validate_options(Array $options) {
return true;
// TODO validate required and unique taxonomy
}
/**
* Validate item based on field type categores options
*
* @param TainacanEntitiesItem_Metadata_Entity $item_metadata
* @return bool Valid or not
*/
public function validate(\Tainacan\Entities\Item_Metadata_Entity $item_metadata) {
$item = $item_metadata->get_item();
$field = $item_metadata->get_field();
if ( !in_array($item->get_status(), apply_filters('tainacan-status-require-validation', ['publish','future','private'])) )
return true;
$valid = true;
if (false === $this->get_option('allow_new_terms')) {
$terms = $item_metadata->get_value();
if (!is_array($terms))
$terms = array($terms);
foreach ($terms as $term) {
if (is_object($term) && $term instanceof \WP_Term) {
$term = $term->term_id;
}
if (!term_exists($term)) {
$valid = false;
break;
}
}
}
return $valid;
}
}

View File

@ -9,8 +9,32 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
*/
abstract class Field_Type {
/**
* Indicates the type of variable that this field type handles.
*
* This is used to relate Field types and filter types, so we know which filter types
* will be available to be used for each field based on its Field Type
*
* For instance, the Filter Type "input text" may be used to search in any field that has
* a Field Type with a string primitive type.
*
* @var string
*/
private $primitive_type;
public $options;
/**
* Array of options spececific to this field type. Stored in field_type_options property of the Field object
* @var Array
*/
public $options = [];
/**
* The default values for the field type options array
* @var Array
*/
public $default_options = [];
public $errors;
/**
@ -70,6 +94,32 @@ abstract class Field_Type {
public function set_options( $options ){
$this->options = ( is_array( $options ) ) ? $options : unserialize( $options );
}
public function set_default_options(Array $options) {
$this->default_options = $options;
}
/**
* Gets the options for this field types, including default values for options
* that were not set yet.
* @return Array Fielt type options
*/
public function get_options() {
return array_merge($this->default_options, $this->options);
}
/**
* Gets one option from the options array.
*
* Checks if option exist or if it have a default value. Otherwise return an empty string
*
* @param string $key the desired option
* @return mixed the option value, the default value or an empty string
*/
public function get_option($key) {
$options = $this->get_options();
return isset($options[$key]) ? $options[$key] : '';
}
/**
* generate the fields for this field type

View File

@ -11,26 +11,29 @@ class Item_Metadata extends Repository {
public function insert($item_metadata) {
$unique = !$item_metadata->is_multiple();
$field_type = $item_metadata->get_field()->get_field_type_object();
if ($field_type->core) {
$this->save_core_field_value($item_metadata);
} elseif ($field_type->get_primitive_type() == 'term') {
$this->save_terms_field_value($item_metadata);
} else {
if ($unique) {
update_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id(), wp_slash( $item_metadata->get_value() ) );
} else {
delete_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id());
if (is_array($item_metadata->get_value())){
$values = $item_metadata->get_value();
if ($unique) {
$field_type = $item_metadata->get_field()->get_field_type_object();
if ($field_type->core) {
$this->save_core_field_value($item_metadata);
} else {
update_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id(), wp_slash( $item_metadata->get_value() ) );
}
} else {
delete_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id());
if (is_array($item_metadata->get_value())){
$values = $item_metadata->get_value();
foreach ($values as $value){
add_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id(), wp_slash( $value ));
}
}
}
foreach ($values as $value){
add_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id(), wp_slash( $value ));
}
}
}
}
do_action('tainacan-insert', $item_metadata);
do_action('tainacan-insert-Item_Metadata_Entity', $item_metadata);
@ -60,6 +63,14 @@ class Item_Metadata extends Repository {
}
}
}
public function save_terms_field_value($item_metadata) {
$field_type = $item_metadata->get_field()->get_field_type_object();
if ($field_type->get_primitive_type() == 'term') {
$new_terms = $item_metadata->get_value();
wp_set_object_terms($item_metadata->get_item()->get_id(), $new_terms, $field_type->get_option('taxonomy_id'));
}
}
/**
* Fetch Item Field objects related to an Item
@ -110,7 +121,16 @@ class Item_Metadata extends Repository {
$get_method = 'get_' . $field_type->related_mapped_prop;
return $item->$get_method();
} elseif ($field_type->get_primitive_type() == 'term') {
$terms = wp_get_object_terms($item_metadata->get_item()->get_id(), $field_type->get_option('taxonomy_id'));
if ($unique)
$terms = reset($terms);
return $terms;
} else {
return get_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id(), $unique);
}

View File

@ -118,7 +118,7 @@ abstract class Repository {
return false;
if ($map[$prop]['map'] == 'meta') {
update_post_meta($obj->get_id(), $prop, wp_slash( $obj->get_mapped_property($prop) ));
update_post_meta($obj->get_id(), $prop, $this->maybe_add_slashes( $obj->get_mapped_property($prop) ));
} elseif($map[$prop]['map'] == 'meta_multi') {
$values = $obj->get_mapped_property($prop);
@ -126,11 +126,18 @@ abstract class Repository {
if (is_array($values)){
foreach ($values as $value){
add_post_meta($obj->get_id(), $prop, wp_slash( $value ));
add_post_meta($obj->get_id(), $prop, $this->maybe_add_slashes( $value ));
}
}
}
}
function maybe_add_slashes($value) {
if (is_string($value) && strpos($value, '\\') !== false) {
return wp_slash($value);
}
return $value;
}
/**
* Prepare the output for the fetch() methods.

View File

@ -88,6 +88,7 @@ $Tainacan_Fields->register_field_type('Tainacan\Field_Types\Numeric');
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Selectbox');
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Relationship');
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Radio');
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Category');
global $Tainacan_Filters;
$Tainacan_Filters = new \Tainacan\Repositories\Filters();

View File

@ -0,0 +1,116 @@
<?php
namespace Tainacan\Tests;
/**
* Class TestCollections
*
* @package Test_Tainacan
*/
use Tainacan\Entities;
/**
* Sample test case.
*/
class CategoryFieldTypes extends TAINACAN_UnitTestCase {
function test_category_field_types() {
global $Tainacan_Item_Metadata, $Tainacan_Items, $Tainacan_Fields, $Tainacan_Terms;
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test',
),
true
);
$tax = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
'name' => 'tax_test',
'collections' => [$collection],
),
true
);
$field = $this->tainacan_entity_factory->create_entity(
'field',
array(
'name' => 'metadado',
'description' => 'title',
'collection' => $collection,
'field_type' => 'Tainacan\Field_Types\Category',
'field_type_options' => [
'taxonomy_id' => $tax->get_db_identifier(),
'allow_new_terms' => false
]
),
true
);
$field2 = $this->tainacan_entity_factory->create_entity(
'field',
array(
'name' => 'metadado_desc',
'description' => 'description',
'collection' => $collection,
'field_type' => 'Tainacan\Field_Types\Category'
),
true
);
$i = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item test',
'description' => 'adasdasdsa',
'collection' => $collection,
'status' => 'publish',
),
true
);
/** TODO test existing term
$term = new \Tainacan\Entities\Term();
$term->set_name('Red');
$term->validate();
$term = $Tainacan_Terms->insert($term);
$item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($i, $field);
$item_metadata->set_value('Red');
$this->assertTrue($item_metadata->validate(), 'item metadata should validate because it is an existing term');
$Tainacan_Item_Metadata->insert($item_metadata);
**/
$item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($i, $field);
$item_metadata->set_value('love');
$this->assertFalse($item_metadata->validate(), 'item metadata should not validate because it does not allow new terms');
// Lets change it
$options = $field->get_field_type_options();
$options['allow_new_terms'] = true;
$field->set_field_type_options($options);
$field->validate();
$field = $Tainacan_Fields->insert($field);
$item_metadata->set_field($field);
$this->assertTrue($item_metadata->validate(), 'item metada should validate because it now allows new terms');
$Tainacan_Item_Metadata->insert($item_metadata);
$checkItem = $Tainacan_Items->fetch($i->get_id());
$check_item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($checkItem, $field);
$this->assertEquals('WP_Term', get_class($check_item_metadata->get_value()));
}
}

View File

@ -194,7 +194,7 @@ class Fields extends TAINACAN_UnitTestCase {
*/
function test_metadata_field_type(){
global $Tainacan_Fields;
$this->assertEquals( 7, sizeof( $Tainacan_Fields->fetch_field_types() ) );
$this->assertEquals( 8, sizeof( $Tainacan_Fields->fetch_field_types() ) );
}