Merge branch 'develop' of github.com:tainacan/tainacan into develop

This commit is contained in:
Jacson Passold 2018-03-01 12:35:10 -03:00
commit 6522030837
50 changed files with 560 additions and 285 deletions

View File

@ -15,12 +15,12 @@ if [ $current_OS == "Darwin" ]; then
find src -type f \( -name "*.js" -or -name "*.vue" \) -exec md5 {} \; | sort -k 2 | md5 > last-js-build.md5
find src -type f \( -name "*.scss" \) -exec md5 {} \; | sort -k 2 | md5 > last-sass-build.md5
find src -type f \( -name "composer.json" \) -exec md5 {} \; | sort -k 2 | md5 > last-composer-build.md5
find src -type f \( -name "package.json" \) -exec md5 {} \; | sort -k 2 | md5 > last-package-build.md5
find src -type f \( -name "package.json" -or -name "package-lock.json" \) -exec md5 {} \; | sort -k 2 | md5 > last-package-build.md5
else
find src -type f \( -name "*.js" -or -name "*.vue" \) -exec md5sum {} \; | sort -k 2 | md5sum > last-js-build.md5
find src -type f \( -name "*.scss" \) -exec md5sum {} \; | sort -k 2 | md5sum > last-sass-build.md5
find src -type f \( -name "composer.json" \) -exec md5sum {} \; | sort -k 2 | md5sum > last-composer-build.md5
find src -type f \( -name "package.json" \) -exec md5sum {} \; | sort -k 2 | md5sum > last-package-build.md5
find src -type f \( -name "package.json" -or -name "package-lock.json" \) -exec md5sum {} \; | sort -k 2 | md5sum > last-package-build.md5
fi
new_md5_package=$(<last-package-build.md5)

View File

@ -89,12 +89,13 @@ class Admin {
'nonce' => wp_create_nonce( 'wp_rest' ),
'components' => $components,
'i18n' => $tainacan_admin_i18n,
'user_caps' => $user_caps
'user_caps' => $user_caps,
'base_url' => $TAINACAN_BASE_URL
];
wp_localize_script( 'tainacan-user-admin', 'wp_settings', $settings );
wp_localize_script( 'tainacan-user-admin', 'tainacan_plugin', $settings );
}

View File

@ -66,7 +66,7 @@
</p>
<p>Nenhuma coleção ainda neste repositório.</p>
<router-link tag="button" class="button is-primary"
:to="{ path: `/collections/new` }">
:to="{ path: $routerHelper.getNewCollectionPath() }">
Criar Coleção
</router-link>
</div>
@ -162,10 +162,10 @@ export default {
handleSelectionChange(value) {
},
goToCollectionPage(collectionId) {
this.$router.push(`/collections/${collectionId}`);
this.$router.push(this.$routerHelper.getCollectionPath(collectionId));
},
goToCollectionEditPage(collectionId) {
this.$router.push(`/collections/${collectionId}/edit`);
this.$router.push(this.$routerHelper.getCollectionEditPath(collectionId));
},
onChangeCollectionsPerPage(value) {
this.collectionsPerPage = value;

View File

@ -41,7 +41,7 @@ export default {
name: 'PrimaryMenu',
data(){
return {
logoHeader: '../wp-content/plugins/tainacan/admin/images/tainacan_logo_header.png',
logoHeader: tainacan_plugin.base_url + '/admin/images/tainacan_logo_header.png',
wordpressAdmin: window.location.origin + window.location.pathname.replace('admin.php', ''),
isCompressed: false,
activeRoute: '/collections'

View File

@ -31,7 +31,7 @@ export default {
name: 'SecondaryMenu',
data(){
return {
logoHeader: '../wp-content/plugins/tainacan/admin/images/tainacan_logo_header.png',
logoHeader: tainacan_plugin.base_url + '/admin/images/tainacan_logo_header.png',
activeRoute: 'ItemsList'
}
},
@ -93,7 +93,7 @@ export default {
transition: padding 0.3s linear;
}
a:hover {
background-color: white;
background-color: $primary-lighter;
color: $secondary
}
a.is-active {

View File

@ -25,7 +25,7 @@ import FieldsList from '../components/fields-list.vue'
Vue.use(VueRouter);
const i18nGet = function (key) {
let string = wp_settings.i18n[key];
let string = tainacan_plugin.i18n[key];
return (string != undefined && string != null && string != '' ) ? string : "ERROR: Invalid i18n key!";
}

View File

@ -6,7 +6,7 @@ I18NPlugin.install = function (Vue, options = {}) {
Vue.prototype.$i18n = {
get(key) {
let string = wp_settings.i18n[key];
let string = tainacan_plugin.i18n[key];
return (string != undefined && string != null && string != '' ) ? string : "ERROR: Invalid i18n key!";
}
}

View File

@ -5,12 +5,20 @@
<div class="columns">
<div class="column">
<b-field :label="$i18n.get('label_active_fields')" is-grouped>
<draggable class="active-fields-area" :class="{'fields-receive': isDraggingFromAvailable}" :list="activeFieldList" :options="{group:'fields'}">
<div class="field-item active" v-for="(field, index) in activeFieldList" :key="index">
<label class="label">{{ field.name }} <b-icon is-small icon="pencil"></b-icon><b-icon is-small icon="delete"></b-icon></label>
<b-field>
<component :is="field.component"></component>
</b-field>
<draggable
class="box active-fields-area"
@change="handleChange"
:class="{'fields-area-receive': isDraggingFromAvailable}"
:list="activeFieldList"
:options="{group:'fields', chosenClass: 'sortable-chosen', filter: '.not-sortable-item'}">
<div
class="active-field-item"
:class="{'not-sortable-item': field.id == undefined}"
v-for="(field, index) in activeFieldList" :key="index">
{{ field.name }}
<span class="label-details"><span class="loading-spinner" v-if="field.id == undefined"></span> (not configured)</span>
<a @click.prevent="removeField(field)" v-if="field.id != undefined"><b-icon is-small icon="delete"></b-icon></a>
<b-icon is-small icon="pencil" v-if="field.id != undefined"></b-icon>
</div>
<div slot="footer">Drag and drop Fields here to add them to Collection.</div>
</draggable>
@ -18,11 +26,9 @@
</div>
<div class="column">
<b-field :label="$i18n.get('label_available_fields')" is-grouped>
<draggable class="available-fields-area" :list="availableFieldList" @start="isDraggingFromAvailable=true" @end="isDraggingFromAvailable=false" :options="{ group: { name:'fields', pull: 'clone', put: 'false' }}">
<div class="field-item" v-for="(field, index) in availableFieldList" :key="index">
<b-field :label="field.name">
<component :is="field.component"></component>
</b-field>
<draggable class="box available-fields-area" :list="availableFieldList" :options="{ group: { name:'fields', pull: 'clone', put: 'false', revertClone: 'true' }}">
<div class="available-field-item" v-for="(field, index) in availableFieldList" :key="index">
{{ field.name }}
</div>
</draggable>
</b-field>
@ -38,70 +44,174 @@ export default {
name: 'CollectionFieldsEditionPage',
data(){
return {
//availableFieldList: ['text', 'textarea', 'numeric', 'select', 'radio', 'checkbox', 'relationship', 'categories'],
activeFieldList: [],
collectionId: '',
isDraggingFromAvailable: false,
isLoadingFieldTypes: true
isLoadingFieldTypes: true,
isLoadingFields: false
}
},
methods: {
...mapActions('collection', [
'fetchFieldTypes'
'fetchFieldTypes',
'fetchFields',
'sendField',
'deleteField',
'updateCollectionFieldsOrder'
]),
...mapGetters('collection',[
'getFieldTypes'
'getFieldTypes',
'getFields'
]),
handleChange($event) {
if ($event.added) {
this.addNewField($event.added.element, $event.added.newIndex);
} else if ($event.removed) {
this.removeField($event.removed.element);
} else if ($event.moved) {
this.updateFieldsOrder();
}
},
updateFieldsOrder() {
let fieldsOrder = [];
for (let field of this.activeFieldList) {
fieldsOrder.push({'id': field.id, 'enabled': true});
}
this.updateCollectionFieldsOrder({ collectionId: this.collectionId, fieldsOrder: fieldsOrder });
},
addNewField(newField, newIndex) {
this.sendField({collectionId: this.collectionId, name: newField.name, fieldType: newField.className, status: 'publish'})
.then((field) => {
this.activeFieldList.splice(newIndex, 1, field);
this.updateFieldsOrder();
})
.catch((error) => {
console.log(error);
});
},
removeField(removedField) {
this.deleteField({ collectionId: this.collectionId, fieldId: removedField.id })
.then((field) => {
let index = this.activeFieldList.findIndex(deletedField => deletedField.id === field.id);
if (index >= 0) {
this.activeFieldList.splice(index, 1);
}
this.updateFieldsOrder();
})
.catch((error) => {
});
}
},
computed: {
availableFieldList() {
return this.getFieldTypes();
},
activeFieldList() {
return this.getFields();
}
},
created() {
this.isLoadingFieldTypes = true;
this.isLoadingFields = true;
this.collectionId = this.$route.params.id;
this.fetchFieldTypes()
.then((res) => {
//console.log(res);
this.isLoadingFieldTypes = false;
})
.catch((error) => {
this.isLoadingFieldTypes = false;
});
this.fetchFields(this.collectionId)
.then((res) => {
this.isLoadingFields = false;
})
.catch((error) => {
this.isLoadingFields = false;
});
}
}
</script>
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
.active-fields-area {
min-height: 40px;
padding: 10px;
&.fields-area-receive {
background-color: whitesmoke;
border: 1px dashed gray;
}
.active-field-item {
background-color: white;
padding: 0.2em 0.5em;
margin: 10px;
border-radius: 5px;
border: 1px solid gainsboro;
display: block;
cursor: grab;
.icon { float: right }
.label-details {
font-weight: normal;
font-style: italic;
color: gray;
}
.loading-spinner {
animation: spinAround 500ms infinite linear;
border: 2px solid #dbdbdb;
border-radius: 290486px;
border-right-color: transparent;
border-top-color: transparent;
content: "";
display: inline-block;
height: 1em;
width: 1em;
}
&.not-sortable-item {
color: gray;
}
}
.active-field-item:hover {
box-shadow: 0px 0px 2px #777;
}
.sortable-chosen {
background-color: $primary-lighter;
padding: 0.2em 0.5em;
margin: 10px;
border-radius: 5px;
border: 3px dashed $primary-light;
display: block;
}
}
.available-fields-area {
padding: 10px;
border: 1px dashed gray;
border-radius: 5px;
background-color: ghostwhite;
}
.active-fields-area {
min-height: 40px;
padding: 10px;
border: 1px solid gray;
border-radius: 5px;
}
.fields-receive {
background-color: whitesmoke;
border: 1px dashed gray;
}
.field-item {
padding: 0.2em 0.5em;
margin: 10px;
border-radius: 5px;
display: inline-block;
border: 1px solid gray;
}
.field-item:hover {
border: 1px dashed gray;
}
.active {
display: block;
.icon { float: right }
.available-field-item {
padding: 0.2em 0.5em;
margin: 10px;
border-radius: 5px;
background-color: white;
border: 1px solid gainsboro;
display: inline-flex;
cursor: grab;
}
.available-field-item:hover {
border: 1px solid lightgrey;
box-shadow: 0px 0px 2px #777;
}
}
</style>

View File

@ -8,9 +8,9 @@ $secondary: #1F2F56;
$secondary-invert: findColorInvert($primary);
$primary-light:#A5CDD7;
$primary-lighter: lighten($primary-light, 4);
$primary-lighter: lighten($primary-light, 10%);
$primary-dark: #55A0AF;
$primary-darker: darken($primary-dark, 4);
$primary-darker: darken($primary-dark, 5%);
// Setup $colors to use as bulma classes
$colors: (

View File

@ -22,58 +22,6 @@ class TAINACAN_REST_Controller extends WP_REST_Controller {
return $object;
}
/**
* @param $entity
*
* @param $map
* @param $context
*
* @return array
*/
protected function get_only_needed_attributes($entity, $map, $context = null){
$entity_prepared = [
'id' => $entity->get_id(),
'description' => $entity->get_description(),
];
if($context === 'edit'){
$entity_prepared['current_user_can_edit'] = $entity->can_edit();
}
if(array_key_exists('modification_date', $map)){
$entity_prepared['modification_date'] = $entity->get_modification_date();
}
if(array_key_exists('creation_date', $map)){
$entity_prepared['creation_date'] = $entity->get_creation_date();
}
if(array_key_exists('author_id', $map)){
$entity_prepared['author_id'] = $entity->get_author_id();
}
if(array_key_exists('name', $map)){
$entity_prepared['name'] = $entity->get_name();
} elseif(array_key_exists('title', $map)){
$entity_prepared['title'] = $entity->get_title();
}
if(array_key_exists('featured_image', $map)){
$entity_prepared['featured_image'] = $entity->get_featured_img();
}
if(array_key_exists('columns', $map)){
$entity_prepared['columns'] = $entity->get_columns();
}
if(array_key_exists('status', $map)){
$entity_prepared['status'] = $entity->get_status();
}
return $entity_prepared;
}
/**
* @param $request
*
@ -170,7 +118,7 @@ class TAINACAN_REST_Controller extends WP_REST_Controller {
$request_meta_query = $request[$mapped];
// If is a multidimensional array (array of array)
if($this->contains_array($request_meta_query)) {
if($this->contains_array($request_meta_query, $query)) {
foreach ( $request_meta_query as $index1 => $a ) {
foreach ( $query as $mapped_meta => $meta_v ) {
if ( isset( $a[ $meta_v ] ) ) {
@ -192,11 +140,14 @@ class TAINACAN_REST_Controller extends WP_REST_Controller {
/**
* @param $array
*
* @param $query
*
* @return bool
*/
protected function contains_array($array){
foreach ($array as $value){
if(is_array($value)){
protected function contains_array($array, $query){
foreach ($array as $index => $value){
// Not will pass named meta query, which use reserved names
if(is_array($value) && !key_exists($index, $query)){
return true;
}
}

View File

@ -82,9 +82,6 @@ class TAINACAN_REST_Collections_Controller extends TAINACAN_REST_Controller {
$collections = $this->collections_repository->fetch($args);
$map = $this->collections_repository->get_map();
$response = [];
if($collections->have_posts()){
while ($collections->have_posts()){
@ -92,7 +89,7 @@ class TAINACAN_REST_Collections_Controller extends TAINACAN_REST_Controller {
$collection = new Entities\Collection($collections->post);
array_push($response, $this->get_only_needed_attributes($collection, $map, $request['context']));
array_push($response, $this->prepare_item_for_response($collection, $request));
}
wp_reset_postdata();
@ -156,8 +153,8 @@ class TAINACAN_REST_Collections_Controller extends TAINACAN_REST_Controller {
* @throws Exception
*/
public function get_items_permissions_check($request){
if ( 'edit' === $request['context'] && ! current_user_can('edit_tainacan-collections') ) {
$dummy = new Entities\Collection();
if ( 'edit' === $request['context'] && ! current_user_can($dummy->get_capabilities()->edit_posts) ) {
return false;
}
@ -233,7 +230,7 @@ class TAINACAN_REST_Collections_Controller extends TAINACAN_REST_Controller {
* @throws Exception
*/
public function create_item_permissions_check( $request ) {
return $this->collections_repository->can_edit($this->collection);
return $this->collection->can_edit();
}
/**

View File

@ -1,9 +1,6 @@
<?php
use Tainacan\Field_Types;
class TAINACAN_REST_Field_Types_Controller extends TAINACAN_REST_Controller {
private $field_type;
/**
* TAINACAN_REST_Field_Types_Controller constructor.

View File

@ -161,7 +161,13 @@ class TAINACAN_REST_Item_Metadata_Controller extends TAINACAN_REST_Controller {
$field = $this->field_repository->fetch( $field_id );
$item_metadata = new Entities\Item_Metadata_Entity( $item, $field );
$item_metadata->set_value( $value );
if($item_metadata->is_multiple()) {
$item_metadata->set_value( $value );
} elseif(is_array($value)) {
$item_metadata->set_value(implode(' ', $value));
} else{
$item_metadata->set_value($value);
}
if ( $item_metadata->validate() ) {
if($item->can_edit()) {

View File

@ -78,27 +78,6 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_REST_Controller {
));
}
/**
* @param $item_object
* @param $item_array
*
* @return mixed
*/
private function add_terms_to_item($item_object, $item_array){
$item_terms = $item_object->get_terms();
foreach ($item_terms as $index => $term){
$term_id = $term['term_id'];
$item_array['terms'][$term_id]['name'] = $term['name'];
$item_array['terms'][$term_id]['description'] = $term['description'];
$item_array['terms'][$term_id]['taxonomy'] = $term['taxonomy'];
}
return $item_array;
}
/**
* @param $item_object
* @param $item_array
@ -134,8 +113,7 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_REST_Controller {
$item_arr['current_user_can_edit'] = $item->can_edit();
}
$prep = $this->add_metadata_to_item($item, $item_arr);
return $this->add_terms_to_item($item, $prep);
return $this->add_metadata_to_item($item, $item_arr);
}
return $item;
@ -167,8 +145,6 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_REST_Controller {
$collection_id = $request['collection_id'];
$items = $this->items_repository->fetch($args, $collection_id, 'WP_Query');
$map = $this->items_repository->get_map();
$response = [];
if ($items->have_posts()) {
while ( $items->have_posts() ) {
@ -176,11 +152,9 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_REST_Controller {
$item = new Entities\Item($items->post);
$limited_item = $this->get_only_needed_attributes($item, $map, $request['context']);
$limited_item = $this->add_metadata_to_item($item, $limited_item);
$limited_item = $this->add_terms_to_item($item, $limited_item);
$prepared_item = $this->prepare_item_for_response($item, $request);
array_push($response, $limited_item);
array_push($response, $prepared_item);
}
wp_reset_postdata();

View File

@ -78,16 +78,14 @@ class TAINACAN_REST_Logs_Controller extends TAINACAN_REST_Controller {
$logs = $this->logs_repository->fetch($args);
$map = $this->logs_repository->get_map();
$response = [];
if($logs->have_posts()){
while ($logs->have_posts()){
$logs->the_post();
$collection = new Entities\Log($logs->post);
$log = new Entities\Log($logs->post);
array_push($response, $this->get_only_needed_attributes($collection, $map));
array_push($response, $this->prepare_item_for_response($log, $request));
}
wp_reset_postdata();

View File

@ -5,7 +5,7 @@ use Tainacan\Repositories\Repository;
class Capabilities {
protected $defaults = [
"tainacan-collections"=> [
"tainacan-collection"=> [
"administrator"=> [
"delete_posts",
"delete_private_posts",
@ -93,7 +93,7 @@ class Capabilities {
"read"
]
],
"tainacan-filters"=> [
"tainacan-filter"=> [
"administrator"=> [
"delete_posts",
"delete_private_posts",
@ -137,7 +137,7 @@ class Capabilities {
"read"
]
],
"tainacan-taxonomies"=> [
"tainacan-taxonomy"=> [
"administrator"=> [
"delete_posts",
"delete_private_posts",
@ -181,7 +181,7 @@ class Capabilities {
"read"
]
],
"tainacan-logs"=> [
"tainacan-log"=> [
"administrator"=> [
"delete_posts",
"delete_private_posts",
@ -276,7 +276,7 @@ class Capabilities {
*/
function __construct() {
add_action('init', array(&$this, 'init'), 11);
add_action('tainacan-insert-tainacan-collections', array(&$this, 'new_collection'));
add_action('tainacan-insert-tainacan-collection', array(&$this, 'new_collection'));
add_action('tainacan-add-collection-moderators', array(&$this, 'add_moderators'), 10, 2);
add_action('tainacan-remove-collection-moderators', array(&$this, 'remove_moderators'), 10, 2);

View File

@ -14,7 +14,7 @@ class Collection extends Entity {
* @see \Tainacan\Entities\Entity::post_type
* @var string
*/
protected static $post_type = 'tainacan-collections';
protected static $post_type = 'tainacan-collection';
/**
* {@inheritDoc}
* @see \Tainacan\Entities\Entity::repository

View File

@ -27,6 +27,12 @@ class Entity {
*/
protected static $post_type = false;
/**
* The WordPress capability for the entity post type. Default is to be equal to $post_type
* @var string
*/
protected static $capability_type = false;
/**
* Store the WordPress post object
* @var \WP_Post
@ -227,6 +233,10 @@ class Entity {
return static::$post_type;
}
public static function get_capability_type() {
return false !== static::$capability_type ? static::$capability_type : static::$post_type;
}
public function get_status(){
$value = $this->get_mapped_property('status');
if(empty($value)) $value = 'draft';
@ -345,9 +355,9 @@ class Entity {
* @return object Object with all the capabilities as member variables.
*/
public function get_capabilities() {
$args = [
$args = [
'map_meta_cap' => true,
'capability_type' => self::get_post_type(),
'capability_type' => self::get_capability_type(),
'capabilities' => array()
];

View File

@ -10,7 +10,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Filter extends Entity {
use \Tainacan\Traits\Entity_Collection_Relation;
protected static $post_type = 'tainacan-filters';
protected static $post_type = 'tainacan-filter';
/**
* {@inheritDoc}

View File

@ -180,6 +180,11 @@ class Item_Metadata_Entity extends Entity {
return false;
}
} else {
if( is_array($value) ){
$this->add_error('not_multiple', $field->get_name() . ' do not accept array as value');
return false;
}
if ($this->is_collection_key()) {
$Tainacan_Items = new \Tainacan\Repositories\Items();
@ -198,9 +203,7 @@ class Item_Metadata_Entity extends Entity {
return false;
}
}
// TODO: call fieldType validation
//
$this->set_as_valid();
return true;
}

View File

@ -8,7 +8,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
* Represents entity Log
*/
class Log extends Entity {
protected static $post_type = 'tainacan-logs';
protected static $post_type = 'tainacan-log';
/**
* {@inheritDoc}
* @see \Tainacan\Entities\Entity::repository

View File

@ -9,8 +9,21 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
*/
class Taxonomy extends Entity {
use \Tainacan\Traits\Entity_Collections_Relation;
protected static $post_type = 'tainacan-taxonomies';
/**
* {@inheritDoc}
* @see \Tainacan\Entities\Entity::post_type
* @var string
*/
protected static $post_type = 'tainacan-taxonomy';
/**
* {@inheritDoc}
* @see \Tainacan\Entities\Entity::capability_type
* @var string
*/
protected static $capability_type = ['tainacan-taxonomy', 'tainacan-taxonomies'];
/**
* {@inheritDoc}
* @see \Tainacan\Entities\Entity::repository

View File

@ -37,12 +37,7 @@ abstract class Field_Type {
abstract function render( $itemMetadata );
public function __construct(){
add_action('register_field_types', array(&$this, 'register_field_type'));
}
public function register_field_type(){
global $Tainacan_Fields;
$Tainacan_Fields->register_field_type( $this );
}
public function validate(\Tainacan\Entities\Item_Metadata_Entity $item_metadata) {

View File

@ -44,8 +44,8 @@
<script>
export default {
created(){
if( this.typeRange ) {
this.type = this.typeRange;
if( this.typerange ) {
this.type = this.typerange;
}
},
data(){
@ -54,7 +54,7 @@
value_end: 0,
date_init: new Date,
date_end: new Date,
type: 'date'
type: 'numeric'
}
},
props: {
@ -62,7 +62,8 @@
type: Object // concentrate all attributes field id and type
},
field_id: [Number], // not required, but overrides the filter field id if is set
typeRange: [String], // not required, but overrides the filter field type if is set
collection_id: [Number], // not required, but overrides the filter field id if is set
typerange: [String], // not required, but overrides the filter field type if is set
id: ''
},
methods: {
@ -82,23 +83,34 @@
}
}
},
// emit the operation for component listener
// emit the operation for listeners
emit(){
let values = [];
let type = ''
if( this.type === 'date' ){
this.$emit('input', {
filter: 'range',
type: 'date',
field_id: ( this.field_id ) ? this.field_id : this.filter.field,
values: [ this.date_init, this.date_end ]
});
let date_init = this.date_init.getUTCFullYear() + '-' +
('00' + (this.date_init.getUTCMonth() + 1)).slice(-2) + '-' +
('00' + this.date_init.getUTCDate()).slice(-2);
let date_end = this.date_end.getUTCFullYear() + '-' +
('00' + (this.date_end.getUTCMonth() + 1)).slice(-2) + '-' +
('00' + this.date_end.getUTCDate()).slice(-2);
values = [ date_init, date_end ];
type = 'DATE';
} else {
this.$emit('input', {
filter: 'range',
type: 'numeric',
field_id: ( this.field_id ) ? this.field_id : this.filter.field,
values: [ this.value_init, this.value_end ]
});
values = [ this.value_init, this.value_end ];
type = 'DECIMAL';
}
this.$emit('input', {
filter: 'range',
type: type,
compare: 'BETWEEN',
field_id: ( this.field_id ) ? this.field_id : this.filter.field,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: values
});
},
// message for error
error_message(){

View File

@ -19,8 +19,11 @@ class Range extends Filter_Type {
* @return string
*/
public function render( $filter ){
return '<tainacan-filter-range
$type = ( $filter->get_field()->get_field_type() === 'Tainacan\Field_Types\Date' ) ? 'date' : 'numeric';
return '<tainacan-filter-range
name="'.$filter->get_name().'"
typeRange="'.$type.'"
collection_id="'.$filter->get_collection_id().'"
field_id="'.$filter->get_field()->get_id().'"></tainacan-filter-range>';
}
}

View File

@ -0,0 +1,112 @@
<template>
<div class="block">
<b-field>
<b-select
:id = "id"
:laoding = "isLoading"
v-model = "selected"
@input = "onSelect()"
expanded>
<option
v-for="option,index in options"
:key="index"
:label="option.label"
:value="option.value"
border>{{ option.label }}</option>
</b-select>
</b-field>
</div>
</template>
<script>
import axios from '../../../js/axios/axios'
export default {
created(){
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.loadOptions();
},
data(){
return {
isLoading: false,
options: [],
type: '',
collection: '',
selected: '',
}
},
props: {
filter: {
type: Object // concentrate all attributes field id and type
},
field_id: [Number], // not required, but overrides the filter field id if is set
collection_id: [Number], // not required, but overrides the filter field id if is set
filter_type: [String], // not required, but overrides the filter field type if is set
id: ''
},
methods: {
getValuesPlainText( field_id ){
// TODO: get values from items
},
getValuesCategory( taxonomy ){
// TODO: get taxonomy terms
},
getValuesRelationship( collectionTarget ){
return axios.get( '/collection/' + collectionTarget + '/items' )
.then( res => {
for (let item of res.data) {
this.options.push({ label: item.title, value: item.id })
}
})
.catch(error => {
console.log(error);
});
},
loadOptions(){
let promise = null;
this.isLoading = true;
if ( this.type === 'Tainacan\Field_types\Relationship' ) {
let collectionTarget = ( this.filter && this.filter.field.field_type_options.collection_id ) ?
this.filter.field.field_type_options.collection_id : this.collection_id;
promise = this.getValuesRelationship( collectionTarget );
} else if ( this.type === 'Tainacan\Field_types\Category' ) {
let collectionTarget = ( this.filter && this.filter.field.field_type_options.taxonomy ) ?
this.filter.field.field_type_options.taxonomy : this.taxonomy;
promise = this.getValuesCategory( collectionTarget );
} else {
promise = this.getValuesPlainText( this.filter.field.id );
}
promise.then( data => {
this.isLoading = false;
})
.catch( error => {
console.log('error select', error );
this.isLoading = false;
});
},
onSelect(){
let filter = null;
if ( this.type ) {
filter = 'term';
} else {
filter = 'selectbox';
}
this.$emit('input', {
filter: filter,
field_id: ( this.field_id ) ? this.field_id : this.filter.field,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: this.selected
});
}
}
}
</script>

View File

@ -19,6 +19,8 @@ class Selectbox extends Filter_Type {
*/
public function render( $filter ){
return '<tainacan-filter-selectbox name="'.$filter->get_name().'"></tainacan-filter-selectbox>';
return '<tainacan-filter-selectbox name="'.$filter->get_name().'"
collection_id="'.$filter->get_collection_id().'"
field_id="'.$filter->get_field()->get_id().'"></tainacan-filter-selectbox>';
}
}

View File

@ -208,7 +208,7 @@ class Collections extends Repository {
'query_var' => true,
'can_export' => true,
'rewrite' => true,
'capability_type' => 'tainacan-collection', // hardcode because post_type is in plural
'capability_type' => Entities\Collection::get_capability_type(),
'map_meta_cap' => true,
'supports' => [
'title',

View File

@ -206,7 +206,7 @@ class Fields extends Repository {
'can_export' => true,
'rewrite' => true,
'map_meta_cap' => true,
'capability_type' => Entities\Field::get_post_type(),
'capability_type' => Entities\Field::get_capability_type(),
'supports' => [
'title',
'editor',

View File

@ -106,7 +106,7 @@ class Filters extends Repository {
'can_export' => true,
'rewrite' => true,
'map_meta_cap' => true,
'capability_type' => Entities\Field::get_post_type(),
'capability_type' => Entities\Field::get_capability_type(),
'supports' => [
'title',
'editor',

View File

@ -118,8 +118,6 @@ class Items extends Repository {
public function insert($item) {
global $Tainacan_Fields;
$map = $this->get_map();
// get collection to determine post type
@ -159,22 +157,7 @@ class Items extends Repository {
add_post_meta($id, $prop, wp_slash( $value ));
}
}
} elseif($mapped['map'] == 'terms'){
$values = $item->get_mapped_property($prop);
if($values) {
$res = [];
foreach ($values as $value){
$taxonomy = get_term($value)->taxonomy;
$res[] = wp_set_post_terms( $item->WP_Post->ID, $value, $taxonomy );
}
if ( ! is_array( $res ) ) {
throw new \InvalidArgumentException( 'The id of post or taxonomy name or term name may be invalid. Response = ' . $res );
}
}
}
}
}
do_action('tainacan-insert', $item);

View File

@ -133,7 +133,7 @@ class Logs extends Repository {
'can_export' => true,
'rewrite' => true,
'map_meta_cap' => true,
'capability_type' => Entities\Log::get_post_type(),
'capability_type' => Entities\Log::get_capability_type(),
'supports' => [
'title',
'editor',
@ -210,7 +210,7 @@ class Logs extends Repository {
$msn = "";
if(is_object($new_value)) {
// do not log a log
if(method_exists($new_value, 'get_post_type') && $new_value->get_post_type() == 'tainacan-logs'){
if(method_exists($new_value, 'get_post_type') && $new_value->get_post_type() == 'tainacan-log'){
return;
}

View File

@ -314,24 +314,6 @@ abstract class Repository {
$property = $attachments_prepared;
}
} elseif ($mapped === 'terms'){
$taxonomies = get_taxonomies('', 'names');
$terms_prepared = [];
foreach($taxonomies as $taxonomy){
if(stristr($taxonomy, 'tnc_tax_')) {
$terms = isset( $entity->WP_Post->ID ) ? wp_get_post_terms( $entity->WP_Post->ID, $taxonomy ) : null;
if ( is_array( $terms ) ) {
foreach ( $terms as $term ) {
$term = new Entities\Term( $term->term_id, $term->taxonomy );
array_push( $terms_prepared, $term->__toArray() );
}
}
}
}
$property = $terms_prepared;
} else {
$property = isset($entity->WP_Post->$mapped) ? $entity->WP_Post->$mapped : null;
}
@ -388,7 +370,7 @@ abstract class Repository {
public static function get_entity_by_post_type($post_type, $post = 0) {
$prefix = substr($post_type, 0, strlen(Entities\Collection::$db_identifier_prefix));
// its is a collection Item?
// Is it a collection Item?
if($prefix == Entities\Collection::$db_identifier_prefix) {
$cpts = self::get_collections_db_identifier();
if(array_key_exists($post_type, $cpts)) {

View File

@ -90,7 +90,7 @@ class Taxonomies extends Repository {
'can_export' => true,
'rewrite' => true,
'map_meta_cap' => true,
'capability_type' => Entities\Taxonomy::get_post_type(),
'capability_type' => Entities\Taxonomy::get_capability_type(),
'supports' => [
'title',
'editor',

View File

@ -81,6 +81,8 @@ global $Tainacan_Fields;
$Tainacan_Fields = new \Tainacan\Repositories\Fields();
//register field types
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Core_Title');
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Core_Description');
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Text');
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Textarea');
$Tainacan_Fields->register_field_type('Tainacan\Field_Types\Date');
@ -88,7 +90,6 @@ $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\Checkbox');
global $Tainacan_Filters;
$Tainacan_Filters = new \Tainacan\Repositories\Filters();

View File

@ -40,7 +40,7 @@ class DevInterface {
];
wp_enqueue_script( 'tainacan-dev-admin', $TAINACAN_BASE_URL . '/assets/dev_admin-components.js', [] , null, true);
wp_localize_script( 'tainacan-dev-admin', 'wp_settings', $settings );
wp_localize_script( 'tainacan-dev-admin', 'tainacan_plugin', $settings );
}
function add_admin_css() {

View File

@ -1,9 +1,9 @@
import axios from 'axios';
const instance = axios.create({
baseURL: wp_settings.root
baseURL: tainacan_plugin.root
});
instance.defaults.headers.common['X-WP-Nonce'] = wp_settings.nonce;
instance.defaults.headers.common['X-WP-Nonce'] = tainacan_plugin.nonce;
export default instance;

View File

@ -1,17 +1,27 @@
import Vue from 'vue';
import store from './store/store'
export const eventFilterBus = new Vue({
store,
data: {
componentsTag: [],
errors : [],
query: {}
},
created(){
this.$on('input', data => this.search(data) );
this.$on('input', data => this.add_metaquery(data) );
},
methods: {
search( ){
console.log( data );
add_metaquery( data ){
if ( data && data.collection_id ){
this.$store.dispatch('filter/add_metaquery', data );
const promisse = this.$store.dispatch('filter/search_by_collection', data.collection_id );
promisse.then( response => {
}, error => {
});
}
},
/* Dev interfaces methods */
@ -37,7 +47,9 @@ export const eventFilterBus = new Vue({
const components = this.getAllComponents();
for (let eventElement of components){
eventElement.addEventListener('input', (event) => {
console.log( event.detail, 'dev' );
if( event.detail ) {
this.add_metaquery( event.detail[0] );
}
});
}
},

View File

@ -8,8 +8,8 @@ export const eventBus = new Vue({
errors : []
},
created(){
if( wp_settings.components ){
this.componentsTag = wp_settings.components;
if( tainacan_plugin.components ){
this.componentsTag = tainacan_plugin.components;
}
this.$on('input', data => this.updateValue(data) );
},

View File

@ -21,6 +21,7 @@ import Date from '../classes/field-types/date/Date.vue';
import Relationship from '../classes/field-types/relationship/Relationship.vue';
import FilterRange from '../classes/filter-types/range/Range.vue';
import FilterSelectbox from '../classes/filter-types/selectbox/Selectbox.vue';
Vue.customElement('tainacan-text', Text);
eventBus.registerComponent( 'tainacan-text' );
@ -53,4 +54,7 @@ eventBus.listener();
Vue.customElement('tainacan-filter-range', FilterRange);
eventFilterBus.registerComponent( 'tainacan-filter-range' );
Vue.customElement('tainacan-filter-selectbox', FilterSelectbox);
eventFilterBus.registerComponent( 'tainacan-filter-selectbox' );
eventFilterBus.listener();

View File

@ -55,6 +55,37 @@ export const fetchFields = ({ commit }, id) => {
});
}
export const sendField = ( { commit }, { collectionId, name, fieldType, status }) => {
return new Promise(( resolve, reject ) => {
axios.post('/collection/'+ collectionId + '/fields/', {
name: name,
field_type: fieldType,
status: status
})
.then( res => {
commit('setField', { collection_id: collectionId, name: name, field_type: fieldType, status: status });
resolve( res.data );
})
.catch(error => {
reject( error.response );
});
});
};
export const deleteField = ({ commit }, { collectionId, fieldId }) => {
return new Promise((resolve, reject) => {
axios.delete('/collection/' + collectionId + '/fields/' + fieldId)
.then( res => {
commit('deleteField', { fieldId } );
resolve( res.data );
}).catch((error) => {
console.log(error);
reject( error );
});
});
};
export const fetchCollection = ({ commit }, id) => {
return new Promise((resolve, reject) =>{
axios.get('/collections/' + id)
@ -99,6 +130,20 @@ export const updateCollection = ({ commit }, { collection_id, name, description,
});
}
export const updateCollectionFieldsOrder = ({ commit }, { collectionId, fieldsOrder }) => {
return new Promise((resolve, reject) => {
axios.patch('/collections/' + collectionId, {
fields_order: fieldsOrder
}).then( res => {
commit('setCollection', res.data);
resolve( res.data );
}).catch( error => {
reject( error.response );
});
});
}
export const sendCollection = ( { commit }, { name, description, status }) => {
return new Promise(( resolve, reject ) => {
axios.post('/collections/', {
@ -130,4 +175,8 @@ export const sendCollection = ( { commit }, { name, description, status }) => {
reject(error);
});
});
}
}
export const setItems = ({ commit }, items ) => {
commit('setItems', items);
};

View File

@ -9,6 +9,13 @@ export const deleteItem = ( state, item ) => {
}
}
export const deleteField = ( state, field ) => {
let index = state.fields.findIndex(deletedField => deletedField.id === field.id);
if (index >= 0) {
state.fields.splice(index, 1);
}
}
export const deleteCollection = ( state, collection ) => {
let index = state.collections.findIndex(deletedCollection => deletedCollection.id === collection.id);
if (index >= 0) {
@ -20,6 +27,16 @@ export const setCollections = (state, collections) => {
state.collections = collections;
}
export const setSingleField = (state, field) => {
let index = state.fields.findIndex(newField => newField.id === field.id);
if ( index >= 0){
//state.field[index] = field;
Vue.set( state.fields, index, field );
} else {
state.fields.push( field );
}
}
export const setFields = (state, fields) => {
state.fields = fields;
}

View File

@ -1,14 +1,31 @@
import axios from '../../../axios/axios';
import qs from 'qs';
export const do_query = ({ commit, state }) => {
return new Promise((resolve, reject) =>{
axios.get('/collections/' + state.collection + '/items?' + qs.stringify( state.query ))
.then(res => {
})
.catch(error => {
})
export const search_by_collection = ({ state, dispatch, rootGetters }, collectionId) => {
return new Promise((resolve, reject) =>{
axios.get('/collection/' + collectionId + '/items?' + qs.stringify( state.postquery ))
.then(res => {
resolve( res.data );
dispatch('collection/setItems', res.data, { root: true } );
})
.catch(error => {
reject( error )
})
});
}
};
export const set_postquery_attribute = ({ commit }, field, value ) => {
commit('setPostQuery', { attr: field, value: value } );
};
export const add_metaquery = ( { commit }, filter ) => {
commit('addMetaQuery', filter );
};
export const remove_metaquery = ( { commit }, filter ) => {
commit('removeMetaQuery', filter );
};

View File

@ -1,7 +1,11 @@
export const getQuery = state => {
return state.query;
export const getPostQuery = state => {
return state.postquery;
}
export const getCollection = state => {
return state.collection;
export const getMetaQuery = state => {
return state.metaquery;
}
export const getTaxQuery = state => {
return state.taxquery;
}

View File

@ -3,8 +3,12 @@ import * as getters from './getters';
import * as mutations from './mutations';
const state = {
query: {},
collection: null
postquery: {
post_status: 'publish',
post_type: [],
metaquery: [],
taxquery: []
}
};
export default {

View File

@ -1,8 +1,31 @@
export const setQuery = ( state, query ) => {
state.query = query;
}
import Vue from 'vue';
export const setCollection = ( state, collection ) => {
state.query = collection;
}
export const setPostQuery = ( state, { attr, value }) => {
Vue.set( state.postquery, attr , value );
};
export const addMetaQuery = ( state, filter ) => {
let index = state.postquery.metaquery.findIndex( item => item.key === filter.field_id);
if ( index >= 0){
Vue.set( state.postquery.metaquery, index, {
key: filter.field_id,
value: filter.value,
compare: filter.compare,
type: filter.type
} );
}else{
state.postquery.metaquery.push({
key: filter.field_id,
value: filter.value,
compare: filter.compare,
type: filter.type
});
}
};
export const removeMetaQuery = ( state, filter ) => {
let index = state.postquery.metaquery.findIndex( item => item.key === filter.field_id);
if (index >= 0) {
state.metaquery.splice(index, 1);
}
}

View File

@ -13,7 +13,7 @@ export const setSingleField = ( state, field) => {
if ( index >= 0){
//state.field[index] = field;
Vue.set( state.fields, index, field );
}else{
} else {
state.fields.push( field );
}
}

View File

@ -3,12 +3,14 @@ import Vuex from 'vuex';
import item from './modules/item/';
import collection from './modules/collection/';
import filter from './modules/filter/';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
item,
collection
collection,
filter
}
})

View File

@ -3,7 +3,7 @@
namespace Tainacan\Tests;
/**
* @group queries
* @group api
* **/
class TAINACAN_REST_Queries extends TAINACAN_UnitApiTestCase {
@ -78,7 +78,6 @@ class TAINACAN_REST_Queries extends TAINACAN_UnitApiTestCase {
'description' => 'Item in collection A',
'status' => 'publish',
'collection' => $collectionA,
'terms' => [$termA]
],
true
);
@ -90,7 +89,6 @@ class TAINACAN_REST_Queries extends TAINACAN_UnitApiTestCase {
'description' => 'Item in collection A',
'status' => 'private',
'collection' => $collectionA,
'terms' => [$termA]
],
true
);
@ -285,6 +283,9 @@ class TAINACAN_REST_Queries extends TAINACAN_UnitApiTestCase {
]
];
wp_set_post_terms($itemA1->get_id(), $termA, $taxonomyA->get_db_identifier());
wp_set_post_terms($itemA2->get_id(), $termA, $taxonomyA->get_db_identifier());
$tax_query_request_collections = new \WP_REST_Request('GET', $this->namespace . '/collection/' . $collectionA->get_id() . '/items');
$tax_query_request_collections->set_query_params($tax_query);

View File

@ -194,18 +194,10 @@ class Fields extends TAINACAN_UnitTestCase {
*/
function test_metadata_field_type(){
global $Tainacan_Fields;
$this->assertEquals( 8, sizeof( $Tainacan_Fields->fetch_field_types() ) );
}
/**
* test if the defaults types are registered
*/
function test_metadata_field_type_insert(){
global $Tainacan_Fields;
$class = new RandomType;
$this->assertEquals( 9, sizeof( $Tainacan_Fields->fetch_field_types() ) );
}
/**
*
*/