IMerge conflicts in web components

This commit is contained in:
mateuswetah 2018-04-09 20:00:49 -03:00
commit ee8174682e
36 changed files with 702 additions and 226 deletions

View File

@ -276,13 +276,6 @@ Return if field is key
Return the mask
**Returns:** string
### `function get_privacy()`
Return the privacy type
**Returns:** string
### `function get_default_value()`

View File

@ -21,6 +21,14 @@ Items are the actual content of yout repository. The painting, the film, the boo
In WordPress language, each item is a post and its post type represents its collection.
### Document
Document is the main information of the item. It is the object which all metadata refer to. Tainacan accepts 3 different document types:
* Attachment: A file attached to the item. An image, video, pdf, audio or other media file.
* URL: An URL pointing to an external website or file. It can be a general website, a specific file, or media services. In the case of media services, Tainacan recognizes addresses and displays the appropriate player, using [oEmbed](https://oembed.com/)
* Text: A plain text, stored directly in the database, the user can type upon creating or editing an item
## Fields
Every collection have a set of fields. They are the description of the items of this collection.

View File

@ -139,7 +139,6 @@ A REST API for Tainacan Plugin. This API uses the Wordpress REST API.
"collection_key": "string",
"multiple": "string",
"cardinality": "string",
"privacy": "string",
"mask": "string",
"default_value": "string",
"field_type_options": "string",

View File

@ -142,7 +142,7 @@
id="button-submit-item-creation"
@click.prevent="onSubmit"
class="button is-success"
:disabled="formHasErrors">{{ $i18n.get('save') }}</button>
>{{ $i18n.get('save') }}</button>
</div>
</div>
<p class="help is-danger">{{ formErrorMessage }}</p>
@ -222,14 +222,13 @@ export default {
this.$router.push(this.$routerHelper.getItemPath(this.form.collectionId, this.itemId));
})
.catch((errors) => {
// for (let error of errors.errors) {
// for (let attribute of Object.keys(error)){
// //this.editFormErrors[attribute] = error[attribute];
// this.$console.log(error);
// eventBus.errors.push({ field_id: 7031, errors: error[attribute]});
// }
// }
this.$console.log(errors);
for (let error of errors.errors) {
for (let attribute of Object.keys(error)){
eventBus.errors.push({ field_id: attribute, errors: error[attribute]});
}
}
this.$console.log(eventBus.errors);
this.formErrorMessage = errors.error_message;
this.isLoading = false;

View File

@ -26,18 +26,17 @@
v-for="(column, index) in tableFields"
:key="index"
:custom-key="column.slug"
:label="column.label"
:label="column.name"
:visible="column.visible"
:width="column.field == 'row_actions' ? 78 : column.field == 'featured_image' ? 55 : undefined ">
<router-link
tag="span"
class="clickable-row"
:to="{path: $routerHelper.getItemPath(collectionId, props.row.id)}">
<template v-if="column.field != 'featured_image' && column.field != 'row_actions'">
{{ showValue( props.row.metadata[column.slug] ) }}
</template>
</router-link>
<template>
<span
class="clickable-row"
@click.prevent="goToItemPage(props.row.id)"
v-if="column.field != 'featured_image' && column.field != 'row_actions'"
v-html="renderMetadata( props.row.metadata[column.slug] )" />
</template>
<template v-if="column.field == 'featured_image'">
<router-link
@ -85,7 +84,7 @@
</div>
</section>
</template>
</b-table>
</b-table>
</div>
</template>
@ -179,20 +178,14 @@ export default {
goToItemEditPage(itemId) {
this.$router.push(this.$routerHelper.getItemEditPath(this.collectionId, itemId));
},
showValue( metadata ){
renderMetadata( metadata ){
if( ! metadata || metadata.value === false || metadata.value == undefined || metadata.value == '' )
if( ! metadata || metadata.value === false || metadata.value == undefined )
return '';
if( metadata.value instanceof Array ){
let result = [];
for( let val of metadata.value ){
result.push( ( val.name ) ? val.name : val )
}
return result.join(', ');
} else {
return metadata.value.name ? metadata.value.name : metadata.value
}
else if (metadata)
return metadata.value_as_html;
else
return metadata.value_as_html;
}
}
}

View File

@ -37,7 +37,7 @@
<script>
import { mapGetters } from 'vuex';
import { eventSearchBus } from '../../../js/event-search-bus'
import { eventSearchBus } from '../../../js/event-search-bus';
export default {
name: 'Pagination',

View File

@ -14,7 +14,6 @@
class="control"
custom>
<b-checkbox
@input="onChangeTableFields(column)"
v-model="column.visible"
:native-value="column.field">
{{ column.label }}
@ -24,73 +23,62 @@
</div>
<div class="header-item">
<b-field>
<b-select :placeholder="$i18n.get('label_sorting')">
<option
v-for="(field, index) in tableFields"
:value="field"
:key="index">
{{ field.label }}
</option>
</b-select>
<button>
<b-icon icon="sort-ascending"/>
</button>
<b-select
@input="onChangeOrderBy($event)"
:placeholder="$i18n.get('label_sorting')">
<option
v-for="(field, index) in tableFields"
v-if="field.id != undefined && field.field_type != 'Tainacan\Field_Types\Core_Description'"
:value="field"
:key="index">
{{ field.name }}
</option>
</b-select>
<button
class="button is-small"
@click="onChangeOrder()">
<b-icon :icon="order == 'ASC' ? 'sort-ascending' : 'sort-descending'"/>
</button>
</b-field>
</div>
</span>
</template>
<script>
import { mapActions } from 'vuex';
import { mapGetters } from 'vuex';
import { eventSearchBus } from '../../../js/event-search-bus';
export default {
name: 'SearchControl',
data() {
return {
prefTableFields: []
}
},
props: {
collectionId: Number,
isRepositoryLevel: false,
tableFields: Array,
prefTableFields: Array,
tableFields: Array
},
methods: {
...mapActions('fields', [
'fetchFields'
]),
onChangeTableFields(field) {
// let prevValue = this.prefTableFields;
// let index = this.prefTableFields.findIndex(alteredField => alteredField.slug === field.slug);
// if (index >= 0) {
// prevValue[index].visible = this.prefTableFields[index].visible ? false : true;
// }
// for (let currentField of this.prefTableFields)
// this.$console.log(currentField.slug, currentField.visible);
// for (let oldField of prevValue)
// this.$console.log(oldField.slug, oldField.visible);
// this.$userPrefs.set('table_columns_' + this.collectionId, this.prefTableFields, prevValue);
computed: {
orderBy() {
return this.getOrderBy();
},
order() {
return this.getOrder();
}
},
mounted() {
this.fetchFields({ collectionId: this.collectionId, isRepositoryLevel: this.isRepositoryLevel, isContextEdit: false }).then((res) => {
let rawFields = res;
this.tableFields.push({ label: this.$i18n.get('label_thumbnail'), field: 'featured_image', slug: 'featured_image', visible: true });
for (let field of rawFields) {
this.tableFields.push(
{ label: field.name, field: field.description, slug: field.slug, visible: true }
);
}
this.tableFields.push({ label: this.$i18n.get('label_actions'), field: 'row_actions', slug: 'actions', visible: true });
this.prefTableFields = this.tableFields;
// this.$userPrefs.get('table_columns_' + this.collectionId)
// .then((value) => {
// this.prefTableFields = value;
// })
// .catch((error) => {
// this.$userPrefs.set('table_columns_' + this.collectionId, this.prefTableFields, null);
// });
}).catch();
methods: {
...mapGetters('search', [
'getOrderBy',
'getOrder'
]),
onChangeOrderBy(field) {
eventSearchBus.setOrderBy(field);
},
onChangeOrder() {
this.order == 'DESC' ? eventSearchBus.setOrder('ASC') : eventSearchBus.setOrder('DESC');
}
}
}
</script>

View File

@ -113,7 +113,7 @@
for (let event of eventsList)
event['by'] = this.$i18n.get('info_by') +
event['user_name'] + '<br>' + this.$i18n.get('info_date') +
moment(event['log_date'], 'YYYY-MM-DD').format('DD/MM/YYYY');
moment(event['log_date'], 'YYYY-MM-DD h:mm:ss').format('DD/MM/YYYY, hh:mm:ss');
return eventsList;
}

View File

@ -5,7 +5,6 @@
<div class="sub-header">
<div class="header-item">
<router-link
id="button-item-creation"
tag="button"
class="button is-secondary"
:to="{ path: $routerHelper.getNewItemPath(collectionId) }">
@ -69,6 +68,9 @@ export default {
...mapGetters('collection', [
'getItems'
]),
...mapActions('fields', [
'fetchFields'
]),
},
computed: {
items(){
@ -77,10 +79,29 @@ export default {
},
created() {
this.collectionId = this.$route.params.collectionId;
this.isRepositoryLevel = (this.collectionId == undefined);
this.isRepositoryLevel = (this.collectionId == undefined);
eventSearchBus.$on('isLoadingItems', isLoadingItems => {
this.isLoading = isLoadingItems;
});
this.fetchFields({ collectionId: this.collectionId, isRepositoryLevel: this.isRepositoryLevel, isContextEdit: false }).then((res) => {
let rawFields = res;
this.tableFields.push({ name: this.$i18n.get('label_thumbnail'), field: 'featured_image', field_type: undefined, slug: 'featured_image', id: undefined, visible: true });
for (let field of rawFields) {
this.tableFields.push(field);
}
this.tableFields.push({ name: this.$i18n.get('label_actions'), field: 'row_actions', field_type: undefined, slug: 'actions', id: undefined, visible: true });
//this.prefTableFields = this.tableFields;
// this.$userPrefs.get('table_columns_' + this.collectionId)
// .then((value) => {
// this.prefTableFields = value;
// })
// .catch((error) => {
// this.$userPrefs.set('table_columns_' + this.collectionId, this.prefTableFields, null);
// });
}).catch();
},
mounted(){
eventSearchBus.updateStoreFromURL();
@ -104,11 +125,6 @@ export default {
padding-left: $page-small-side-padding;
padding-right: $page-small-side-padding;
border-bottom: 0.5px solid #ddd;
.header-item {
display: inline-block;
padding-right: 8em;
}
@media screen and (max-width: 769px) {
height: 60px;

View File

@ -154,6 +154,7 @@ html {
// Some components have a different style in listing pages
.button {
border: none;
border-radius: 6px !important;
font-weight: normal;
padding: 2px 15px !important;

View File

@ -103,6 +103,8 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_REST_Controller {
$item_array['metadata'][$slug]['name'] = $field->get_name();
$item_array['metadata'][$slug]['value'] = $item_metadata_array['value'];
$item_array['metadata'][$slug]['value_as_html'] = $item_metadata_array['value_as_html'];
$item_array['metadata'][$slug]['value_as_string'] = $item_metadata_array['value_as_string'];
$item_array['metadata'][$slug]['multiple'] = $field->get_multiple();
}

View File

@ -275,6 +275,7 @@ class Entity {
public function add_error($type, $message) {
$this->errors[] = [$type => $message];
$this->set_validated(false);
}
/**

View File

@ -19,7 +19,6 @@ class Field extends Entity {
$cardinality,
$collection_key,
$mask,
$privacy,
$default_value,
$field_type,
$field_type_options;
@ -131,15 +130,6 @@ class Field extends Entity {
return $this->get_mapped_property('mask');
}
/**
* Return the privacy type
*
* @return string
*/
function get_privacy(){
return $this->get_mapped_property('privacy');
}
/**
* Return the field default value
*
@ -294,16 +284,6 @@ class Field extends Entity {
$this->set_mapped_property('mask', $value);
}
/**
* Set privacy
*
* @param [string] $value
* @return void
*/
function set_privacy( $value ){
$this->set_mapped_property('privacy', $value);
}
/**
* Set default value
*

View File

@ -16,6 +16,13 @@ class Item_Metadata_Entity extends Entity {
*/
protected $repository = 'Item_Metadata';
protected
$item,
$field,
$parent_meta_id,
$meta_id,
$value;
/**
*
* @param Item $item Item Entity
@ -38,25 +45,99 @@ class Item_Metadata_Entity extends Entity {
}
public function __toString(){
return 'Hello, I\'m the Item Field Entity';
public function __value_to_html(){
$field = $this->get_field();
if (is_object($field)) {
$fto = $field->get_field_type_object();
if (is_object($fto)) {
if ( method_exists($fto, '__value_to_html') ) {
return $fto->__value_to_html($this);
}
}
}
$value = $this->get_value();
$return = '';
if ( $this->is_multiple() ) {
$total = sizeof($value);
$count = 0;
foreach ($value as $v) {
$return .= (string) $v;
$count ++;
if ($count <= $total)
$return .= ', ';
}
} else {
$return = (string) $value;
}
return $return;
}
public function __value_to_string() {
return strip_tags($this->__value_to_html());
}
public function __value_to_array() {
$field = $this->get_field();
if (is_object($field)) {
$fto = $field->get_field_type_object();
if (is_object($fto)) {
if ( method_exists($fto, '__value_to_array') ) {
return $fto->__value_to_array($this);
}
}
}
$value = $this->get_value();
if ( $this->is_multiple() ) {
$return = [];
foreach ($value as $v) {
if ( $v instanceof Term || $v instanceof ItemMetadataEntity ) {
$return[] = $v->__toArray();
} else {
$return[] = $v;
}
}
} else {
$return = '';
if ( $value instanceof Term || $value instanceof ItemMetadataEntity ) {
$return = $value->__toArray();
} else {
$return = $value;
}
}
return $return;
}
public function __toArray(){
$value = $this->get_value();
if(is_array($value) && isset($value[0]) && $value[0] instanceof Term){
$values_arr = [];
foreach ($value as $val){
$values_arr[] = $val->__toArray();
}
$as_array['value'] = $values_arr;
} else {
$as_array['value'] = $this->get_value();
}
$as_array = [];
$as_array['value'] = $this->__value_to_array();
$as_array['value_as_html'] = $this->__value_to_html();
$as_array['value_as_string'] = $this->__value_to_string();
$as_array['item'] = $this->get_item()->__toArray();
$as_array['field'] = $this->get_field()->__toArray();
@ -258,7 +339,7 @@ class Item_Metadata_Entity extends Entity {
} else {
if( is_array($value) ){
$this->add_error('not_multiple', $field->get_name() . ' do not accept array as value');
$this->add_error('not_multiple', $field->get_name() . ' do not accept array as value');
return false;
}

View File

@ -23,6 +23,8 @@ class Item extends Entity {
$order,
$parent,
$decription,
$document_type,
$document,
$collection_id;
/**
@ -219,6 +221,24 @@ class Item extends Entity {
function get_description() {
return $this->get_mapped_property( 'description' );
}
/**
* Return the item document type
*
* @return string
*/
function get_document_type() {
return $this->get_mapped_property( 'document_type' );
}
/**
* Return the item document
*
* @return string
*/
function get_document() {
return $this->get_mapped_property( 'document' );
}
/**
*
@ -272,6 +292,28 @@ class Item extends Entity {
$this->set_mapped_property( 'parent', $value );
}
/**
* Define the document type
*
* @param [string] $value
*
* @return void
*/
function set_document_type( $value ) {
$this->set_mapped_property( 'document_type', $value );
}
/**
* Define the document
*
* @param [string] $value
*
* @return void
*/
function set_document( $value ) {
$this->set_mapped_property( 'document', $value );
}
/**
* Define the description
*
@ -324,32 +366,29 @@ class Item extends Entity {
return true;
}
if ( parent::validate() ) {
$arrayItemMetadata = $this->get_fields();
if ( $arrayItemMetadata ) {
foreach ( $arrayItemMetadata as $itemMetadata ) {
$is_valid = true;
// avoid core fields to re-validate
$pos = strpos( $itemMetadata->get_field()->get_field_type(), 'Core' );
if ( $pos !== false ) {
continue;
}
// skip validation for Compound Fields
if ( $itemMetadata->get_field()->get_field_type() == 'Tainacan\Field_Types\Compound' ) {
continue;
}
if ( parent::validate() === false ) {
$is_valid = false;
}
if ( ! $itemMetadata->validate() ) {
$errors = $itemMetadata->get_errors();
$this->add_error( $itemMetadata->get_field()->get_id(), $errors );
$arrayItemMetadata = $this->get_fields();
if ( $arrayItemMetadata ) {
foreach ( $arrayItemMetadata as $itemMetadata ) {
// skip validation for Compound Fields
if ( $itemMetadata->get_field()->get_field_type() == 'Tainacan\Field_Types\Compound' ) {
continue;
}
return false;
}
if ( ! $itemMetadata->validate() ) {
$errors = $itemMetadata->get_errors();
$this->add_error( $itemMetadata->get_field()->get_id(), $errors );
$is_valid = false;
}
}
return true;
return $is_valid;
}
return false;
@ -370,4 +409,29 @@ class Item extends Entity {
return parent::validate();
}
public function __toHtml() {
$return = '';
$id = $this->get_id();
if ( $id ) {
$link = get_permalink( (int) $id );
if (is_string($link)) {
$return = "<a data-linkto='item' data-id='$id' href='$link'>";
$return.= $this->get_title();
$return .= "</a>";
}
}
return $return;
}
}

View File

@ -172,4 +172,79 @@ class Term extends Entity {
function set_taxonomy($value) {
$this->set_mapped_property('taxonomy', $value);
}
/**
*
* {@inheritDoc}
* @see \Tainacan\Entities\Entity::validate()
*/
function validate() {
if (!parent::validate())
return false;
$parent = $this->get_parent();
$name = $this->get_name();
$taxonomy = $this->get_taxonomy();
/**
* Code from WordPress Core, taxonomy.php#2070
*/
/*
* Prevent the creation of terms with duplicate names at the same level of a taxonomy hierarchy,
* unless a unique slug has been explicitly provided.
*/
$name_matches = get_terms( $taxonomy, array(
'name' => $name,
'hide_empty' => false,
'parent' => $parent,
) );
/*
* The `name` match in `get_terms()` doesn't differentiate accented characters,
* so we do a stricter comparison here.
*/
$name_match = null;
if ( $name_matches ) {
foreach ( $name_matches as $_match ) {
if ( strtolower( $name ) === strtolower( $_match->name ) ) {
$name_match = $_match;
break;
}
}
}
if ($name_match) {
$this->add_error( 'repeated', __('You can not have two terms with the same name at the same level', 'tainacan') );
return false;
}
return true;
}
public function __toHtml() {
$return = '';
$id = $this->get_id();
if ( $id ) {
$link = get_term_link( (int) $id );
if (is_string($link)) {
$return = "<a data-linkto='term' data-id='$id' href='$link'>";
$return.= $this->get_name();
$return .= "</a>";
}
}
return $return;
}
}

View File

@ -120,8 +120,8 @@ class Category extends Field_Type {
$terms = array($terms);
foreach ($terms as $term) {
if (is_object($term) && $term instanceof \WP_Term) {
$term = $term->term_id;
if (is_object($term) && $term instanceof \Tainacan\Entities\Term) {
$term = $term->get_id();
}
if (!term_exists($term)) {
@ -136,4 +136,40 @@ class Category extends Field_Type {
}
public function __value_to_html(Item_Metadata_Entity $item_metadata) {
$value = $item_metadata->get_value();
$return = '';
if ( $item_metadata->is_multiple() ) {
$count = 1;
$total = sizeof($value);
foreach ( $value as $term ) {
if ( $term instanceof \Tainacan\Entities\Term ) {
$return .= $term->__toHtml();
}
$count ++;
if ( $count <= $total ) {
$return .= ', ';
}
}
} else {
if ( $value instanceof \Tainacan\Entities\Term ) {
$return .= $value->__toHtml();
}
}
return $return;
}
}

View File

@ -66,4 +66,53 @@ class Relationship extends Field_Type {
}
return true;
}
public function __value_to_html(Item_Metadata_Entity $item_metadata) {
$value = $item_metadata->get_value();
$return = '';
if ( $item_metadata->is_multiple() ) {
$count = 1;
$total = sizeof($value);
foreach ( $value as $item_id ) {
try {
$item = new \Tainacan\Entities\Item($item_id);
if ( $item instanceof \Tainacan\Entities\Item ) {
$return .= $item->__toHtml();
}
$count ++;
if ( $count <= $total ) {
$return .= ', ';
}
} catch (Exception $e) {
// item not found
}
}
} else {
if ( $value instanceof \Tainacan\Entities\Item ) {
$return .= $value->__toHtml();
}
}
return $return;
}
}

View File

@ -71,12 +71,17 @@
return this.inputs;
},
getErrorMessage() {
let msg = '';
let errors = eventBus.getErrors(this.field.field.id);
if ( errors) {
this.setFieldTypeMessage('is-danger');
for (let index in errors) {
msg += errors[index] + '\n';
for (let error of errors) {
for (let index of Object.keys(error)) {
this.$console.log(index);
msg += error[index] + '\n';
}
}
} else {
this.setFieldTypeMessage('');

View File

@ -128,15 +128,6 @@ class Fields extends Repository {
'validation' => v::numeric()->positive(),
'default' => 1
],
'privacy' => [
'map' => 'meta',
'title' => __('Privacy', 'tainacan'),
'type' => 'string',
'description'=> __('The field should be omitted in item view', 'tainacan'),
'on_error' => __('Privacy is invalid', 'tainacan'),
'validation' => v::stringType()->in(['yes', 'no']), // yes or no. It cant be multiple if its collection_key
'default' => 'no'
],
'mask' => [
'map' => 'meta',
'title' => __('Mask', 'tainacan'),
@ -174,15 +165,6 @@ class Fields extends Repository {
'default' => false,
'validation' => v::boolType()
],
'can_delete' => [
'map' => 'meta',
'title' => __('Can delete', 'tainacan'),
'type' => 'string',
'description'=> __('The field can be deleted', 'tainacan'),
'on_error' => __('Can delete is invalid', 'tainacan'),
'validation' => v::stringType()->in(['yes', 'no']), // yes or no. It cant be multiple if its collection_key
'default' => 'yes'
],
]);
}

View File

@ -28,8 +28,21 @@ class Item_Metadata extends Repository {
public function insert($item_metadata) {
$unique = !$item_metadata->is_multiple();
if ( ! $item_metadata->get_validated() ) {
throw new \Exception( 'Entities must be validated before you can save them' );
// TODO: Throw Warning saying you must validate object before insert()
}
$old = $item_metadata;
$is_update = false;
// TODO get props obj before update
if( $item_metadata->get_id() ) {
$is_update = true;
$old = $item_metadata->get_repository()->fetch( $item_metadata->get_id() );
}
$unique = !$item_metadata->is_multiple();
$field_type = $item_metadata->get_field()->get_field_type_object();
if ($field_type->get_core()) {
$this->save_core_field_value($item_metadata);
@ -52,22 +65,22 @@ class Item_Metadata extends Repository {
* and not update an existing. This is the case of a multiple compound field.
*/
if ( $item_metadata->get_field()->get_parent() > 0 && is_null($item_metadata->get_meta_id()) ) {
$added_meta_id = add_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id(), wp_slash( $item_metadata->get_value() ) );
$added_meta_id = add_post_meta($item_metadata->get_item()->get_id(), $item_metadata->get_field()->get_id(), wp_slash( $item_metadata->get_value() ) );
$added_compound = $this->add_compound_value($item_metadata, $added_meta_id);
} else {
update_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id(), wp_slash( $item_metadata->get_value() ) );
update_post_meta($item_metadata->get_item()->get_id(), $item_metadata->get_field()->get_id(), wp_slash( $item_metadata->get_value() ) );
}
}
} else {
delete_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id());
delete_post_meta($item_metadata->get_item()->get_id(), $item_metadata->get_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 ));
add_post_meta($item_metadata->get_item()->get_id(), $item_metadata->get_field()->get_id(), wp_slash( $value ));
}
}
}
@ -75,7 +88,7 @@ class Item_Metadata extends Repository {
do_action('tainacan-insert', $item_metadata);
do_action('tainacan-insert', $item_metadata, $old, $is_update);
do_action('tainacan-insert-Item_Metadata_Entity', $item_metadata);
$new_entity = new Entities\Item_Metadata_Entity($item_metadata->get_item(), $item_metadata->get_field());
@ -222,8 +235,12 @@ class Item_Metadata extends Repository {
$terms = wp_get_object_terms($item_metadata->get_item()->get_id(), $taxonomy_slug );
if ($unique)
if ($unique) {
$terms = reset($terms);
if (false !== $terms)
$terms = new Entities\Term($terms);
}
if(is_array($terms)){
$terms_array = [];
@ -240,7 +257,7 @@ class Item_Metadata extends Repository {
global $wpdb;
$rows = $wpdb->get_results(
$wpdb->prepare("SELECT * FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $item_metadata->get_item()->get_id(), $item_metadata->field->get_id()),
$wpdb->prepare("SELECT * FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $item_metadata->get_item()->get_id(), $item_metadata->get_field()->get_id()),
ARRAY_A );
$return_value = [];
@ -268,7 +285,7 @@ class Item_Metadata extends Repository {
return $value->meta_value;
}
} else {
return get_post_meta($item_metadata->item->get_id(), $item_metadata->field->get_id(), $unique);
return get_post_meta($item_metadata->get_item()->get_id(), $item_metadata->get_field()->get_id(), $unique);
}
}

View File

@ -91,8 +91,23 @@ class Items extends Repository {
'type' => 'array',
'description' => __( 'The item term IDs', 'tainacan' ),
],
//'collection' => 'relation...',
// field .. field...
'document_type' => [
'map' => 'meta',
'title' => __('Document Type', 'tainacan'),
'type' => 'string',
'description'=> __('The document type, can be a local attachment, an external URL or a text', 'tainacan'),
'on_error' => __('Invalid document type', 'tainacan'),
'validation' => v::stringType()->in(['attachment', 'url', 'text']),
'default' => 'attachment'
],
'document' => [
'map' => 'meta',
'title' => __('Document', 'tainacan'),
'type' => 'string',
'description'=> __('The document itself. An ID in case of attachment, an URL in case of url or a text in the case of text', 'tainacan'),
'on_error' => __('Invalid document', 'tainacan'),
'default' => ''
],
] );
}
@ -152,6 +167,14 @@ class Items extends Repository {
public function insert( $item ) {
$old = $item;
$is_update = false;
// TODO get props obj before update
if( $item->get_id() ) {
$is_update = true;
$old = $item->get_repository()->fetch( $item->get_id() );
}
$map = $this->get_map();
// get collection to determine post type
@ -198,7 +221,7 @@ class Items extends Repository {
set_post_thumbnail( $item->WP_Post, $item->get_featured_img_id( $item->WP_Post->ID ) );
}
do_action( 'tainacan-insert', $item );
do_action( 'tainacan-insert', $item, $old, $is_update );
do_action( 'tainacan-insert-Item', $item );
// return a brand new object

View File

@ -28,7 +28,7 @@ class Logs extends Repository {
protected function __construct() {
parent::__construct();
add_action( 'tainacan-insert', array( $this, 'log_inserts' ), 10, 2 );
add_action( 'tainacan-insert', array( $this, 'log_inserts' ), 10, 3 );
}
public function get_map() {
@ -211,6 +211,7 @@ class Logs extends Repository {
$args = [
'post_type' => Entities\Log::get_post_type(),
'posts_per_page' => -1,
'orderby' => 'date',
];
$logs = $this->fetch( $args, 'OBJECT' );
@ -226,7 +227,7 @@ class Logs extends Repository {
*
* @return Entities\Log new created log
*/
public function log_inserts( $new_value, $old_value = null ) {
public function log_inserts( $new_value, $old_value = null, $is_update = null ) {
$msn = "";
$description = "";
@ -242,8 +243,29 @@ class Logs extends Repository {
$name = method_exists($new_value, 'get_name') ? $new_value->get_name() :
(method_exists($new_value, 'get_title') ? $new_value->get_title() : $new_value->get_field()->get_name());
$msn = sprintf( esc_html__( 'A %s has been created/updated.', 'tainacan' ), $class_name);
$description = sprintf( esc_html__("The %s %s has been created/updated.", 'tainacan' ), $name, strtolower($class_name));
$articleA = 'A';
$articleAn = 'An';
$vowels = 'aeiou';
if($is_update){
if(substr_count($vowels, strtolower(substr($class_name, 0, 1))) > 0){
$msn = sprintf( __( '%s %s has been updated.', 'tainacan' ), $articleAn, $class_name);
$description = sprintf( __("The \"%s\" %s has been updated.", 'tainacan' ), $name, strtolower($class_name));
} else {
$msn = sprintf( __( '%s %s has been updated.', 'tainacan' ), $articleA, $class_name);
$description = sprintf( __("The \"%s\" %s has been updated.", 'tainacan' ), $name, strtolower($class_name));
}
} else {
if(substr_count($vowels, strtolower(substr($class_name, 0, 1))) > 0){
$msn = sprintf( __( '%s %s has been created.', 'tainacan' ), $articleAn, $class_name);
$description = sprintf( __("The \"%s\" %s has been created.", 'tainacan' ), $name, strtolower($class_name));
} else {
$msn = sprintf( __( '%s %s has been created.', 'tainacan' ), $articleA, $class_name);
$description = sprintf( __("The \"%s\" %s has been created.", 'tainacan' ), $name, strtolower($class_name));
}
}
}

View File

@ -77,8 +77,10 @@ abstract class Repository {
}
$old = $obj;
$is_update = false;
// TODO get props obj before update
if( $obj->get_id() ) {
$is_update = true;
$old = $obj->get_repository()->fetch( $obj->get_id() );
}
@ -116,7 +118,7 @@ abstract class Repository {
set_post_thumbnail( $obj->WP_Post, $obj->get_featured_img_id( $obj->WP_Post->ID ) );
}
do_action( 'tainacan-insert', $obj, $old );
do_action( 'tainacan-insert', $obj, $old, $is_update );
do_action( 'tainacan-insert-' . $obj->get_post_type(), $obj );
// return a brand new object
@ -364,6 +366,9 @@ abstract class Repository {
return $post;
}
if (!$post instanceof \WP_Post)
return false;
$post_type = $post->post_type;
return self::get_entity_by_post_type( $post_type, $post );
@ -609,6 +614,7 @@ abstract class Repository {
*/
public function diff( $old = 0, $new ) {
$old_entity = null;
if ( $old === 0 ) { // self diff or other entity?
$id = $new->get_id();
if ( ! empty( $id ) ) { // there is a repository entity?
@ -620,6 +626,7 @@ abstract class Repository {
} else { // get entity from repository
$old_entity = $this->get_entity_by_post( $old );
}
$new_entity = $this->get_entity_by_post( $new );
$map = $this->get_map();
@ -628,8 +635,10 @@ abstract class Repository {
foreach ( $map as $prop => $mapped ) {
if ( $old_entity->get_mapped_property( $prop ) != $new_entity->get_mapped_property( $prop ) ) {
if ( $mapped['map'] == 'meta_multi' ) {
$meta_diff = array_diff( $new_entity->get_mapped_property( $prop ), $old_entity->get_mapped_property( $prop ) );
if ( ! empty( $meta_diff ) ) {
$diff[ $prop ] = [
'new' => $new_entity->get_mapped_property( $prop ),
@ -643,8 +652,10 @@ abstract class Repository {
'old' => $old_entity->get_mapped_property( $prop )
];
}
}
}
$diff = apply_filters( 'tainacan-entity-diff', $diff, $new, $old );
return $diff;

View File

@ -100,6 +100,15 @@ class Terms extends Repository {
* @return Entities\Entity|Entities\Term
*/
public function insert($term){
$old = $term;
$is_update = false;
// TODO get props obj before update
if( $term->get_id() ) {
$is_update = true;
$old = $term->get_repository()->fetch( $term->get_id() );
}
// First iterate through the native post properties
$map = $this->get_map();
foreach ($map as $prop => $mapped) {
@ -138,7 +147,7 @@ class Terms extends Repository {
}
}
do_action('tainacan-insert', $term);
do_action('tainacan-insert', $term, $old, $is_update);
do_action('tainacan-insert-Term', $term);
return new Entities\Term($term_saved['term_id'], $term->get_taxonomy());

View File

@ -39,30 +39,31 @@ export const eventBus = new Vue({
let values = ( Array.isArray( data.values[0] ) ) ? data.values[0] : data.values ;
const promisse = this.$store.dispatch('item/updateMetadata',
{ item_id: data.item_id, field_id: data.field_id, values: values });
promisse.then( () => {
let index = this.errors.findIndex( errorItem => errorItem.field_id === data.field_id );
promisse.then( () => {
let index = this.errors.findIndex( errorItem => errorItem.field_id == data.field_id );
if ( index >= 0){
this.errors.splice( index, 1);
}
}).catch((error) => {
let index = this.errors.findIndex( errorItem => errorItem.field_id === data.field_id );
let messages = null;
})
.catch((error) => {
let index = this.errors.findIndex( errorItem => errorItem.field_id == data.field_id );
let messages = [];
for (let index in error) {
messages = error[index]
messages.push(error[index]);
}
if ( index >= 0){
Vue.set( this.errors, index, { field_id: data.field_id, errors: messages });
}else{
} else {
this.errors.push( { field_id: data.field_id, errors: messages } );
}
});
}
},
getErrors(field_id){
let error = this.errors.find( errorItem => errorItem.field_id === field_id );
console.log(this.errors);
let error = this.errors.find( errorItem => errorItem.field_id == field_id );
return ( error ) ? error.errors : false
},
setValues(){

View File

@ -24,6 +24,10 @@ export const eventSearchBus = new Vue({
this.$route.query.perpage = 12;
if (this.$route.query.paged == undefined)
this.$route.query.paged = 1;
if (this.$route.query.order == undefined)
this.$route.query.order = 'DESC';
if (this.$route.query.orderby == undefined)
this.$route.query.orderby = 'date';
store.dispatch('search/set_postquery', this.$route.query);
//console.log(this.$route.query);
@ -59,6 +63,14 @@ export const eventSearchBus = new Vue({
store.dispatch('search/setItemsPerPage', itemsPerPage);
this.updateURLQueries();
},
setOrderBy(newOrderBy) {
store.dispatch('search/setOrderBy', newOrderBy);
this.updateURLQueries();
},
setOrder(newOrder) {
store.dispatch('search/setOrder', newOrder);
this.updateURLQueries();
},
updateURLQueries() {
router.push({ query: {} });
router.push({ query: store.getters['search/getPostQuery'] });

View File

@ -47,7 +47,7 @@ export const fetchFields = ({ commit }, item_id) => {
});
};
export const cleanFields = ({ commit }, item_id) => {
export const cleanFields = ({ commit }) => {
commit('cleanFields');
};

View File

@ -1,3 +1,4 @@
// General Post Queries
export const set_postquery_attribute = ({ commit }, filter, value ) => {
commit('setPostQueryAttribute', { attr: filter, value: value } );
};
@ -6,6 +7,7 @@ export const set_postquery = ({ commit }, postquery ) => {
commit('setPostQuery', postquery );
};
// Meta Queries from filters
export const add_metaquery = ( { commit }, filter ) => {
if( filter && filter.value.length === 0 ){
commit('removeMetaQuery', filter );
@ -18,6 +20,7 @@ export const remove_metaquery = ( { commit }, filter ) => {
commit('removeMetaQuery', filter );
};
// Pagination queries
export const setTotalItems = ({ commit }, total ) => {
commit('setTotalItems', total);
};
@ -28,4 +31,29 @@ export const setPage = ({ commit }, page ) => {
export const setItemsPerPage = ({ commit }, page ) => {
commit('setPostQueryAttribute', { attr: 'perpage', value: page } );
};
};
// Sorting queries
export const setOrderBy = ({ commit }, orderBy ) => {
if (orderBy.field_type == 'Tainacan\\Field_Types\\Numeric') {
commit('addMetaQuery', {
field_id: orderBy.id
});
commit('setPostQueryAttribute', { attr: 'meta_key', value: orderBy.id } );
commit('setPostQueryAttribute', { attr: 'orderby', value: 'meta_value_num' } );
} else if (orderBy.field_type == orderBy.field_type_object.core) {
commit('setPostQueryAttribute', { attr: 'orderby', value: orderBy.field_type_object.related_mapped_prop } );
} else {
commit('addMetaQuery', {
field_id: orderBy.id
});
commit('setPostQueryAttribute', { attr: 'meta_key', value: orderBy.id } );
commit('setPostQueryAttribute', { attr: 'orderby', value: 'meta_value' } );
}
};
export const setOrder = ({ commit }, order ) => {
commit('setPostQueryAttribute', { attr: 'order', value: order } );
};

View File

@ -20,4 +20,12 @@ export const getPage = state => {
export const getItemsPerPage = state => {
return state.postquery.perpage;
};
export const getOrder = state => {
return state.postquery.order;
}
export const getOrderBy = state => {
return state.postquery.orderby;
};

View File

@ -4,6 +4,8 @@ import * as mutations from './mutations';
const state = {
postquery: {
orderby: 'date',
order: 'DESC',
paged: 1,
perpage: 12,
post_type: [],

View File

@ -238,8 +238,10 @@ class TAINACAN_REST_Terms_Controller extends TAINACAN_UnitApiTestCase {
$first_filter = $data[0];
$second_filter = $data[1];
$this->assertEquals($filter->get_name(), $first_filter['name']);
$this->assertEquals($filter2->get_name(), $second_filter['name']);
$names = [$first_filter['name'], $second_filter['name']];
$this->assertContains($filter->get_name(), $names);
$this->assertContains($filter2->get_name(), $names);
#### FETCH A FILTER ####

View File

@ -105,7 +105,7 @@ class TAINACAN_REST_Item_Metadata_Controller extends TAINACAN_UnitApiTestCase {
$pending = $log->get_value();
$this->assertEquals('TestValuesSuggestion_metadado', $pending->value);
$this->assertEquals('TestValuesSuggestion_metadado', $pending->get_value());
wp_set_current_user($this->user_id);
@ -165,7 +165,7 @@ class TAINACAN_REST_Item_Metadata_Controller extends TAINACAN_UnitApiTestCase {
$pending = $log->get_value();
$this->assertEquals('TestValuesAnonymousSuggestion_metadado', $pending->value);
$this->assertEquals('TestValuesAnonymousSuggestion_metadado', $pending->get_value());
wp_set_current_user($this->user_id);

View File

@ -55,6 +55,17 @@ class CategoryFieldTypes extends TAINACAN_UnitTestCase {
true
);
$i = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item test',
'description' => 'adasdasdsa',
'collection' => $collection,
'status' => 'publish',
),
true
);
$field2 = $this->tainacan_entity_factory->create_entity(
'field',
array(
@ -68,16 +79,7 @@ class CategoryFieldTypes extends TAINACAN_UnitTestCase {
);
$i = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item test',
'description' => 'adasdasdsa',
'collection' => $collection,
'status' => 'publish',
),
true
);
$term = $this->tainacan_entity_factory->create_entity(
@ -118,7 +120,7 @@ class CategoryFieldTypes extends TAINACAN_UnitTestCase {
$check_item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($checkItem, $field);
$this->assertEquals('WP_Term', get_class($check_item_metadata->get_value()));
$this->assertEquals('Tainacan\Entities\Term', get_class($check_item_metadata->get_value()));
// test 2 fields with same category
$field2->set_field_type_options([
@ -202,6 +204,72 @@ class CategoryFieldTypes extends TAINACAN_UnitTestCase {
}
function test_values_and_html() {
$Tainacan_Fields = \Tainacan\Repositories\Fields::getInstance();
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::getInstance();
$Tainacan_ItemMetadata = \Tainacan\Repositories\Item_Metadata::getInstance();
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test',
),
true
);
$tax = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
'name' => 'tax_test',
),
true
);
$item = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'orange',
'collection' => $collection,
'status' => 'publish'
),
true
);
$field = $this->tainacan_entity_factory->create_entity(
'field',
array(
'name' => 'meta',
'description' => 'description',
'collection' => $collection,
'field_type' => 'Tainacan\Field_Types\Category',
'status' => 'publish',
'field_type_options' => [
'taxonomy_id' => $tax->get_id(),
'allow_new_terms' => true
]
),
true
);
$meta = new \Tainacan\Entities\Item_Metadata_Entity($item, $field);
$meta->set_value('new_term');
$meta->validate();
$meta = $Tainacan_ItemMetadata->insert($meta);
$this->assertInternalType( 'string', $meta->__value_to_html() );
$this->assertInternalType( 'string', $meta->__value_to_string() );
$this->assertInternalType( 'integer', strpos($meta->__value_to_html(), '<a ') );
$this->assertFalse( strpos($meta->__value_to_string(), '<a ') );
}
}

View File

@ -59,7 +59,9 @@ class Item_Metadata extends TAINACAN_UnitTestCase {
$item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($item, $test);
$item_metadata->set_value('teste_value');
$item_metadata->validate();
$item_metadata = $Tainacan_Item_Metadata->insert($item_metadata);
$this->assertEquals('teste_value', $item_metadata->get_value());

View File

@ -99,7 +99,6 @@ class Logs extends TAINACAN_UnitTestCase {
$log = $Tainacan_Logs->fetch_last();
$diff = $log->diff();
$this->assertEquals('With name', $diff['name']['new']);