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

This commit is contained in:
Leo Germani 2018-02-21 14:08:02 -03:00
commit 2bf300eeca
18 changed files with 1114 additions and 283 deletions

1029
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,8 @@
"buefy": "^0.6.3",
"bulma": "^0.6.2",
"mdi": "^2.1.19",
"node-sass": "^4.7.2",
"sass-loader": "^6.0.6",
"vue": "^2.5.13",
"vuex": "^3.0.1"
},

View File

@ -1,18 +1,24 @@
<template>
<div id="tainacan-admin-app">
<nav class="navbar is-secondary" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<router-link class="navbar-item" to="/">
<img :src="logoHeader" alt="Tainacan Admin" height="32">
</router-link>
<router-link class="navbar-item" to="/collections">{{ $i18n.getString('header', 'collections')}}</router-link>
<div class="columns is-fullheight">
<nav id="primary-menu" role="navigation" aria-label="main navigation" class="column is-2 is-sidebar-menu is-hidden-mobile">
<aside class="menu">
<router-link to="/">
<img :src="logoHeader" alt="Tainacan Admin" height="32">
</router-link>
<ul class="menu-list">
<li><router-link tag="a" to="/collections">{{ $i18n.getString('header', 'collections')}}</router-link></li>
<li><a class="navbar-item">Items</a></li>
<li><a class="navbar-item">Campos</a></li>
<li><a class="navbar-item">Filtros</a></li>
<li><a class="navbar-item">Atividades</a></li>
<li><a class="navbar-item" :href="wordpressAdmin">Admin do Wordpress</a></li>
</ul>
</aside>
</nav>
<div class="container column is-main-content">
<router-view></router-view>
</div>
<a :href="wordpressAdmin" class="is-pulled-right">
<i class="mdi mdi-close mdi-36px mdi-light"></i>
</a>
</nav>
<div class="container">
<router-view></router-view>
</div>
</div>
</template>
@ -28,3 +34,18 @@
}
}
</script>
<style lang="scss">
@import "./scss/_variables.scss";
#primary-menu {
background-color: $primary;
li{
a {color: white !important;}
a:hover {color: $primary !important;}
}
}
</style>

View File

@ -38,25 +38,23 @@
@page-change="onPageChange">
<template slot-scope="props">
<b-table-column field="featured_image" width="55">
<b-table-column field="featured_image" width="55" sortable="false">
<template v-if="props.row.featured_image" slot-scope="scope">
<img class="table-thumb" :src="`${props.row.featured_image}`"/>
</template>
</b-table-column>
<b-table-column label="Nome" field="props.row.name">
<router-link :to="`/collections/${props.row.id}`" tag="a">{{ props.row.name }}</router-link>
{{ props.row.name }}
</b-table-column>
<b-table-column property="description" label="Descrição" show-overflow-tooltip field="props.row.description">
{{ props.row.description }}
</b-table-column>
<b-table-column label="Ações">
<b-table-column label="Ações" width="80">
<a @click.prevent.stop="goToCollectionEditPage(props.row.id)"><b-icon icon="pencil"></a>
<a @click.prevent.stop="deleteOneCollection(props.row.id)"><b-icon icon="delete"></a>
<a @click.prevent.stop="showMoreCollection(props.row.id)"><b-icon icon="dots-vertical"></a>
</b-table-column>
</template>
@ -162,15 +160,12 @@ export default {
});
});
}
this.selectedCollections = [];
}
});
},
handleSelectionChange(value) {
},
showMoreCollection(collectionId) {
},
goToCollectionEditPage(collectionId) {
this.$router.push(`/collections/${collectionId}/edit`);
},
@ -188,7 +183,7 @@ export default {
.then((res) => {
this.isLoading = false;
this.totalCollections = res.total;
})
})
.catch((error) => {
this.isLoading = false;
});
@ -213,6 +208,8 @@ export default {
vertical-align: middle !important;
}
tr { cursor: pointer !important; }
</style>

View File

@ -51,17 +51,17 @@
<b-table-column v-for="(column, index) in tableFields"
:key="index"
:label="column.label"
:visible="column.visible">
:visible="column.visible"
:width="column.field == 'row_actions' ? 80 : column.field == 'featured_image' ? 55 : undefined ">
<template v-if="column.field != 'featured_image' && column.field != 'row_actions'">{{
props.row.metadata[column.label].multiple == 'yes' ? props.row.metadata[column.label].value.join(', ') : props.row.metadata[column.label].value
}}</template>
<template v-if="column.field == 'featured_image'">
<img class="table-thumb" :src="`${ props.row[column.field] }`"/>
</template>
<template v-if="column.field == 'row_actions'">
<template v-if="column.field == 'row_actions'" width="80">
<a @click.prevent.stop="goToItemEditPage(props.row.id)"><b-icon icon="pencil"></a>
<a @click.prevent.stop="deleteOneItem(props.row.id)"><b-icon icon="delete"></a>
<a @click.prevent.stop="showMoreItem(props.row.id)"><b-icon icon="dots-vertical"></a>
</template>
</b-table-column>
@ -181,8 +181,6 @@ export default {
},
handleSelectionChange() {
},
showMoreItem(itemId) {
},
onChangeItemsPerPage(value) {
this.itemsPerPage = value;
this.loadItems();
@ -234,6 +232,8 @@ export default {
vertical-align: middle !important;
}
tr { cursor: pointer }
</style>

View File

@ -0,0 +1,22 @@
// Import Bulma's core and variables
@import "../../../node_modules/bulma/sass/utilities/_all.sass";
// Tainacan custom colors
$primary: #25a189;
$primary-invert: findColorInvert($primary);
$secondary: #01295c;
$secondary-invert: findColorInvert($primary);
// Setup $colors to use as bulma classes
$colors: (
"white": ($white, $black),
"black": ($black, $white),
"light": ($light, $light-invert),
"dark": ($dark, $dark-invert),
"primary": ($primary, $primary-invert),
"secondary": ($secondary, $secondary-invert),
"info": ($info, $info-invert),
"success": ($success, $success-invert),
"warning": ($warning, $warning-invert),
"danger": ($danger, $danger-invert)
);

View File

@ -1,25 +1,5 @@
// Import Bulma's core
@import "../../../node_modules/bulma/sass/utilities/_all.sass";
// Tainacan custom colors
$primary: #25a189;
$primary-invert: findColorInvert($primary);
$secondary: #01295c;
$secondary-invert: findColorInvert($primary);
// Setup $colors to use as bulma classes
$colors: (
"white": ($white, $black),
"black": ($black, $white),
"light": ($light, $light-invert),
"dark": ($dark, $dark-invert),
"primary": ($primary, $primary-invert),
"secondary": ($secondary, $secondary-invert),
"info": ($info, $info-invert),
"success": ($success, $success-invert),
"warning": ($warning, $warning-invert),
"danger": ($danger, $danger-invert)
);
// Tainacan custom colors and bulma's core
@import "./_variables.scss";
// Links
$link: $primary;

View File

@ -74,23 +74,26 @@ class TAINACAN_REST_Controller extends WP_REST_Controller {
*/
protected function prepare_filters($request){
$map = [
'name' => 'title',
'title' => 'title',
'id' => 'p',
'pageid' => 'page_id',
'authorid' => 'author_id',
'authorname' => 'author_name',
'search' => 's',
'status' => 'post_status',
'offset' => 'offset',
'metaquery' => 'meta_query',
'datequery' => 'date_query',
'order' => 'order',
'orderby' => 'orderby',
'metakey' => 'meta_key',
'hideempty' => 'hide_empty',
'perpage' => 'posts_per_page',
'paged' => 'paged'
'name' => 'title',
'title' => 'title',
'id' => 'p',
'pageid' => 'page_id',
'authorid' => 'author_id',
'authorname' => 'author_name',
'search' => 's',
'status' => 'post_status',
'offset' => 'offset',
'metaquery' => 'meta_query',
'datequery' => 'date_query',
'order' => 'order',
'orderby' => 'orderby',
'metakey' => 'meta_key',
'metavalue' => 'meta_value',
'metavaluenum' => 'meta_value_num',
'metacompare' => 'meta_compare',
'hideempty' => 'hide_empty',
'perpage' => 'posts_per_page',
'paged' => 'paged',
];
$meta_query = [
@ -98,16 +101,22 @@ class TAINACAN_REST_Controller extends WP_REST_Controller {
'value' => 'value',
'compare' => 'compare',
'relation' => 'relation',
'type' => 'type',
];
$date_query = [
'year' => 'year',
'month' => 'month',
'day' => 'day',
'week' => 'week',
'hour' => 'hour',
'minute' => 'minute',
'second' => 'second'
'year' => 'year',
'month' => 'month',
'day' => 'day',
'week' => 'week',
'hour' => 'hour',
'minute' => 'minute',
'second' => 'second',
'compare' => 'compare',
'dayofweek' => 'dayofweek',
'inclusive' => 'inclusive',
'before' => 'before',
'after' => 'after',
];
$args = [];
@ -115,31 +124,11 @@ class TAINACAN_REST_Controller extends WP_REST_Controller {
foreach ($map as $mapped => $mapped_v){
if(isset($request[$mapped])){
if($mapped === 'metaquery'){
$request_meta_query = $request[$mapped];
// If is a multidimensional array (array of array)
if($this->contains_array($request_meta_query)) {
foreach ( $request_meta_query as $index1 => $a ) {
foreach ( $meta_query as $mapped_meta => $meta_v ) {
if ( isset( $a[ $meta_v ] ) ) {
$args[ $mapped_v ][ $index1 ][ $meta_v ] = $request[ $mapped ][ $index1 ][ $meta_v ];
}
}
}
} else {
foreach ( $meta_query as $mapped_meta => $meta_v ) {
if(isset($request[$mapped][$meta_v])) {
$args[ $mapped_v ][ $meta_v ] = $request[ $mapped ][ $meta_v ];
}
}
}
} elseif ($mapped === 'datequery') {
foreach ($date_query as $date_meta => $date_v){
$args[$mapped_v][$date_v] = $request[$mapped][$date_meta];
}
} else {
$args = $this->prepare_meta($mapped, $request, $meta_query, $mapped_v, $args);
} elseif($mapped === 'datequery'){
$args = $this->prepare_meta($mapped, $request, $date_query, $mapped_v, $args);
}
else {
$args[ $mapped_v ] = $request[ $mapped ];
}
}
@ -150,6 +139,29 @@ class TAINACAN_REST_Controller extends WP_REST_Controller {
return $args;
}
private function prepare_meta($mapped, $request, $query, $mapped_v, $args){
$request_meta_query = $request[$mapped];
// If is a multidimensional array (array of array)
if($this->contains_array($request_meta_query)) {
foreach ( $request_meta_query as $index1 => $a ) {
foreach ( $query as $mapped_meta => $meta_v ) {
if ( isset( $a[ $meta_v ] ) ) {
$args[ $mapped_v ][ $index1 ][ $meta_v ] = $request[ $mapped ][ $index1 ][ $meta_v ];
}
}
}
} else {
foreach ( $query as $mapped_meta => $meta_v ) {
if(isset($request[$mapped][$meta_v])) {
$args[ $mapped_v ][ $meta_v ] = $request[ $mapped ][ $meta_v ];
}
}
}
return $args;
}
protected function contains_array($array){
foreach ($array as $value){
if(is_array($value)){

View File

@ -210,6 +210,13 @@ class Item extends Entity {
$arrayItemMetadata = $this->get_fields();
if( $arrayItemMetadata ){
foreach ( $arrayItemMetadata as $itemMetadata ) {
// avoid core fields to re-validate
$pos = strpos($itemMetadata->get_field()->get_field_type(), 'Core');
if( $pos !== false ){
continue;
}
if( !$itemMetadata->validate() ){
$errors = $itemMetadata->get_errors();
$this->add_error( $itemMetadata->get_field()->get_name(), $errors );
@ -221,4 +228,15 @@ class Item extends Entity {
}
return false;
}
/**
* {@inheritDoc}
* @see \Tainacan\Entities\Entity::validate()
*/
public function validate_core_fields(){
if ( !in_array($this->get_status(), apply_filters('tainacan-status-require-validation', ['publish','future','private'])) )
return true;
return parent::validate();
}
}

View File

@ -296,8 +296,6 @@ class Fields extends Repository {
* @throws \Exception
*/
public function fetch_by_collection(Entities\Collection $collection, $args = [], $output = null){
$this->register_core_fields( $collection );
$collection_id = $collection->get_id();
//get parent collections

View File

@ -64,7 +64,7 @@ class Item_Metadata extends Repository {
$set_method = 'set_' . $field_type->related_mapped_prop;
$value = $item_metadata->get_value();
$item->$set_method( is_array( $value ) ? $value[0] : $value );
if ($item->validate()) {
if ($item->validate_core_fields()) {
global $Tainacan_Items;
$Tainacan_Items->insert($item);
} else {

View File

@ -475,6 +475,12 @@ class DevInterface {
foreach ($metalist as $meta) {
$item_meta = new \Tainacan\Entities\Item_Metadata_Entity($entity, $meta);
$pos = strpos($item_meta->get_field()->get_field_type(), 'Core');
if( $pos !== false ){
continue;
}
if (isset($_POST['tnc_metadata_' . $meta->get_id()])) {
$item_meta->set_value($_POST['tnc_metadata_' . $meta->get_id()]);
if ($item_meta->validate()) {

View File

@ -4,6 +4,7 @@ use Tainacan;
abstract class Importer {
private $id;
public $collection;
public $mapping;
public $tmp_file;
@ -14,6 +15,16 @@ abstract class Importer {
if (!session_id()) {
@session_start();
}
$this->id = uniqid();
$_SESSION['tainacan_importer'][$this->id] = $this;
}
/**
* @return string
*/
public function get_id(){
return $this->id;
}
/**
@ -21,7 +32,6 @@ abstract class Importer {
*/
public function set_collection( Tainacan\Entities\Collection $collection ){
$this->collection = $collection;
$_SESSION['tainacan_importer'] = $this;
}
/**
@ -29,7 +39,6 @@ abstract class Importer {
*/
public function set_mapping( $mapping ){
$this->mapping = $mapping;
$_SESSION['tainacan_importer'] = $this;
}
/**
@ -41,7 +50,6 @@ abstract class Importer {
if ( is_numeric( $new_file ) ) {
$attach = get_post($new_file);
$this->tmp_file = $attach->guid;
$_SESSION['tainacan_importer'] = $this;
} else {
return false;
}
@ -61,6 +69,22 @@ abstract class Importer {
return media_handle_sideload( $file_array, 0 );
}
/**
* get the content form url and creates a file
*
* @param $url
* @return array
*/
public function fetch_from_remote( $url ){
$tmp = wp_remote_get( $url );
if( isset( $tmp['body'] ) ){
$file = fopen( $this->get_id().'.txt', 'w' );
fwrite( $file, $tmp['body'] );
fclose( $file );
return $this->set_file( $this->get_id().'.txt' );
}
}
/**
* get the fields of file/url to allow mapping
* should returns an array

View File

@ -32,7 +32,7 @@ export const fetchCollections = ({commit} , { page, collectionsPerPage }) => {
let collections = res.data;
commit('setCollections', collections);
resolve({'collections': collections, 'total': res.headers['x-wp-total'] });
})
})
.catch(error => {
console.log(error);
reject(error);

View File

@ -92,6 +92,11 @@ class TAINACAN_REST_Collections_Controller extends TAINACAN_UnitApiTestCase {
$this->assertContains('testeApi', $collectionsNames);
$this->assertContains('Other', $collectionsNames);
<<<<<<< HEAD
=======
$this->assertEquals('Other', $one_collection['name']);
$this->assertEquals('testeApi', $other_collection['name']);
>>>>>>> d3bb9a172b00dad430e8e9a04c2174d368b385e0
}
public function test_delete_or_trash_a_collection(){

View File

@ -164,8 +164,10 @@ class TAINACAN_REST_Queries extends TAINACAN_UnitApiTestCase {
/* Meta Query:
Fetch items from a collection desc ordered by fieldA1 and its only in range A to Y.
*/
*
* Fetch items from a collection desc ordered by fieldA1 and its only in range A to F.
*
* */
$meta_query = [
'metakey' => $fieldA1->get_id(),
@ -188,6 +190,51 @@ class TAINACAN_REST_Queries extends TAINACAN_UnitApiTestCase {
$data3 = $meta_query_response->get_data();
$this->assertCount(2, $data3);
$values = [$data3[0]['metadata']['Field A-1']['value'], $data3[1]['metadata']['Field A-1']['value']];
$this->assertNotContains('G', $values);
// E have to come first, because DESC
$this->assertEquals('E', $data3[0]['metadata']['Field A-1']['value']);
$this->assertEquals('D', $data3[1]['metadata']['Field A-1']['value']);
/* Date Query:
*
* Fetch posts for today
*
* */
$today = getdate();
$date_query = [
'datequery' => [
[
'year' => $today['year'],
'month' => $today['mon'],
'day' => $today['mday']
]
]
];
$date_query_request_collections = new \WP_REST_Request('GET', $this->namespace . '/collections');
$date_query_request_collections->set_query_params($date_query);
$date_query_response_collections = $this->server->dispatch($date_query_request_collections);
$data4 = $date_query_response_collections->get_data();
$this->assertCount(3, $data4);
// If we change the date query for a date different of today, it should return nothing
$date_query['datequery'][0]['year'] = 1995;
$date_query_request_collections->set_query_params($date_query);
$date_query_response_collections = $this->server->dispatch($date_query_request_collections);
$data5 = $date_query_response_collections->get_data();
$this->assertCount(0, $data5);
}
}

View File

@ -26,10 +26,11 @@ class ImporterTests extends TAINACAN_UnitTestCase {
);
$csv_importer = new Importer\CSV();
$csv_importer->set_collection( $collection );
$id = $csv_importer->get_id();
$_SESSION['tainacan_importer'][$id]->set_collection( $collection );
// here the session is init already
$this->assertEquals( $_SESSION['tainacan_importer'], $csv_importer );
$this->assertEquals( $collection->get_id(), $_SESSION['tainacan_importer'][$id]->collection->get_id() );
}
/**
@ -37,6 +38,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
*/
public function test_file_import_csv () {
$csv_importer = new Importer\CSV();
$id = $csv_importer->get_id();
// open the file "demosaved.csv" for writing
$file = fopen('demosaved.csv', 'w');
@ -44,7 +46,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
// save the column headers
fputcsv($file, array('Column 1', 'Column 2', 'Column 3', 'Column 4', 'Column 5'));
// Sample data. This can be fetched from mysql too
// Sample data
$data = array(
array('Data 11', 'Data 12', 'Data 13', 'Data 14', 'Data 15'),
array('Data 21', 'Data 22', 'Data 23', 'Data 24', 'Data 25'),
@ -61,9 +63,19 @@ class ImporterTests extends TAINACAN_UnitTestCase {
// Close the file
fclose($file);
$csv_importer->set_file( 'demosaved.csv' );
$_SESSION['tainacan_importer'][$id]->set_file( 'demosaved.csv' );
// here the session is init already
$this->assertEquals( $_SESSION['tainacan_importer']->tmp_file , $csv_importer->tmp_file );
$this->assertTrue( isset( $_SESSION['tainacan_importer'][$id]->tmp_file ) );
}
/**
* @group importer
*/
public function test_fetch_file(){
$csv_importer = new Importer\CSV();
$id = $csv_importer->get_id();
$_SESSION['tainacan_importer'][$id]->fetch_from_remote( 'http://localhost/wordpress-test/wp-json' );
$this->assertTrue( isset( $_SESSION['tainacan_importer'][$id]->tmp_file ) );
}
}

View File

@ -32,7 +32,7 @@ module.exports = {
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader'],
use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
}
]
},