Merge branch 'develop' into exposers

This commit is contained in:
Jacson Passold 2018-04-23 15:51:52 -03:00
commit c75c8585b2
28 changed files with 409 additions and 262 deletions

View File

@ -29,23 +29,25 @@ Document is the main information of the item. It is the object which all metadat
* 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
## Metadata
Every collection have a set of fields. They are the description of the items of this collection.
Data about the Document.
Each field has a set of settings. Is it required? Is it supposed to be unique (an ID number for example)? Does it accept multiple values? What is it Field Type? (TODO: see the complete list of field attributes).
Every collection declare a set of metadata to describe its documents. This means that the collection the item belongs to will detemine the metadata it will have.
You may have repository-level fields, that will be inherited by all collections of your repository. In the same way, collections inherit fields from their parent collection.
Each metadata has a set of settings. Is it required? Is it supposed to be unique (an ID number for example)? Does it accept multiple values? What is it Metadata Type? (TODO: see the complete list of metadata attributes).
(Note: you can use and import/export presets of fields)
You may have repository-level metadata, that will be inherited by all collections of your repository. In the same way, collections inherit metadata from their parent collection.
## Field Types
(Note: you can use and import/export presets of metadata)
Field types are the objects that represent the types of field that can be used. Examples of Field Types are "Text", "Long text", "Date", "Relationship with another item", etc (TODO: see full list).
## Metadata Types
Each field type object have its own settings and web component that will be used to render the interface.
Metadata types are the objects that represent the types of metadata that can be used. Examples of Metadata Types are "Text", "Long text", "Date", "Relationship with another item", etc (TODO: see full list).
Field Types can be created via plugins and extend the default set of types shipped with Tainacan.
Each metadata type object have its own settings and web component that will be used to render the interface.
Metadata Types can be created via plugins and extend the default set of types shipped with Tainacan.
## Filters
@ -61,11 +63,11 @@ Each Filter Type object have its own settings and web component that will be use
Filter Types can be created via plugins and extend the default set of types shipped with Tainacan.
## Categories
## Taxonomies
Categories (or Taxonomies) can be created and used to classify items. Typical Taxonomies are Genre, Country, etc.
Taxonomies can be created and used to classify items. Typical Taxonomies are Genre, Country, etc.
In WordPress language, they are Taxonomies, and they can be shared among many collections.
In WordPress language, they are Custom Taxonomies, and they can be shared among many collections.
Each Category has a set of terms. For example, the category Genre may have terms like "drama" and "comedy".
@ -77,9 +79,9 @@ Terms also have a description, may have an icon or image that represents it and
Item types gives you the abiity to specialize the desription of an item based on its nature. So, inside the same collection you may have items that vary in its nature and, therefore, have a different set of metadata.
For each item type you can choose a group of Fields, in the same way you do for a collection. When you create an item inside a collection, it will have all the fields chosen for that collection plus the fields related to its type.
For each item type you can choose a group of Metadata, in the same way you do for a collection. When you create an item inside a collection, it will have all the metadata chosen for that collection plus the metadata related to its type.
AN item type can be anything. For example, LPs, Books and paintings are õbvious distinct item types that may have specific fields. But it could also more abstract concepts, such as "financial transactions".
An item type can be anything. For example, LPs, Books and paintings are õbvious distinct item types that may have specific metadata. But it could also more abstract concepts, such as "financial transactions".
## Under discussion
@ -91,8 +93,8 @@ Items in Desktop are not publicly visible and have only the fields configured in
### Thematic Collections
Thematic Collections is another way to organize the items in your repository. In essecen, they are a Category, that can hold items from any collections, and an item can be part of many Thematic Collections.
Thematic Collections is another way to organize the items in your repository. In essence, each thematic collection is a term inside a taxonomy called "Thematic Collections", that can hold items from any collections, and an item can be part of many Thematic Collections.
They work in exactly the same way as categories, the only difference is that you have another way to manage it,..
It work in exactly the same way as any other taxonomy, the only difference is that you have another way to manage it,..
Another idea here is, intead of having a "fixed category" called thematic collections, we could just have a menu item "Categories" or "Organize by categories" that lets you browse the items by category, instead of by collections, and manipulate them.
Another idea here is, intead of having a "fixed taxonomy" called thematic collections, we could just have a menu item "Taxonomies" or "Organize by taxonomies" that lets you browse the items by taxonomy, instead of by collections, and manipulate them.

View File

@ -28,7 +28,7 @@ You wil also need:
* `Node` to handle dependencies and vuild the JS application
```
sudo apt-get install phpunit composer ruby nodejs npm
sudo apt-get install phpunit composer ruby ruby-dev nodejs npm
sudo gem install sass
```
@ -53,9 +53,9 @@ When we want to build the plugin, we run `build.sh` that basically installs any
In order to use it, make a copy of `build-config-sample.sh` and name it only `build-config.sh`. Edit and fill in your environment details:
* `wp_base_dir`: The base directory for you local WordPress installation, used for development and testing. e.g ~/develop/wordpress
* `wp_url`: The base URL for your local WordPress installation/ e.g http://localhost/wp
* `wp_plugin_dir`: The directory for your plugin build. Should be a directory inside `wp_base_dir`. e.g ~/develop/wordpress/wp-content/plugins/test-tainacan
* `wp_base_dir`: The base directory for you local WordPress installation, used for development and testing. e.g `~/develop/wordpress`
* `wp_url`: The base URL for your local WordPress installation/ e.g `http://localhost/wp`
* `wp_plugin_dir`: The directory for your plugin build. Should be a directory inside `wp_base_dir`. e.g `~/develop/wordpress/wp-content/plugins/test-tainacan`
Once you are ready, you can run:
@ -72,6 +72,7 @@ Tainacan uses `phpunit` to run tests for the backend and the API, and `cypress`
To execute all the tests, simply execute the `run-tests` script. But first you need to configure PHPUnit.
#### Preparing PHPUnit
To run the unit tests it is necessary to create a new MySQL database for your unit tests. This database will be cleaned and restored every time you run PHPUnit.
Install the WordPress test library by running the script provided in:
@ -84,7 +85,7 @@ The parameters are:
* Database name
* MySQL username
* MySQL password
* WordPress Test Directory (In order to test the API, this folder must be inside your local webserver)
* WordPress Test Directory
* MySQL host
* WordPress version
* Optional: skip create database
@ -122,8 +123,8 @@ If you want to run front-end tests, opening the Cypress app and beeing able to r
./run-cypress.sh
```
**Important note about the Cypress setup:**
**Important note about the Cypress setup:**
Cypress will use the same local WordPress installation you configure in the build to run its tests. But before it does so, it will edit the `wp-config.php` file and change the `$db_prefix` variable, so, in reality, it will run all the tests in a brand new WordPress installation. After the tests are completed, it delete this installation from the database and restores the `wp-config.php` as it was before. So, make sure you allways let the script run till the end to restore you configuration. For instance, if you opened Cypress window and are running the tests, dont exit it by Ctrl+C in the terminal. Close the window gently and let the script finish its job.
Cypress will use the same local WordPress installation you configure in the build to run its tests. But before it does so, it will edit the `wp-config.php` file and change the `$db_prefix` variable, so, in reality, it will run all the tests in a brand new WordPress installation. After the tests are completed, it deletes this installation from the database and restores the `wp-config.php` as it was before. So, make sure you allways let the script run till the end to restore you configuration. For instance, if you opened Cypress window and are running the tests, dont exit it by Ctrl+C in the terminal. Close the window gently and let the script finish its job.
If, by any reason you interrupt the script, no worries, just manually edit you `wp-config.php` and delete the line added by the script.
If, by any reason, you interrupt the script, no worries, just manually edit you `wp-config.php` and delete the line added by the script.

View File

@ -33,7 +33,7 @@
<div class="media-content">
<div class="content">
<p>
<strong class="is-capitalized">{{ o.title }}</strong> <small>{{ o.mime_type }}</small>
<strong class="is-capitalized">{{ o.title }}</strong> <small class="tag is-light">{{ o.mime_type }}</small>
<br>
{{ o.description }}
</p>
@ -99,7 +99,7 @@
<div class="media-content">
<div class="content">
<p>
<strong class="is-capitalized">{{ d.title }}</strong> <small>{{ d.mime_type }}</small>
<strong class="is-capitalized">{{ d.title }}</strong> <small class="tag is-light">{{ d.mime_type }}</small>
<br>
{{ d.description }}
</p>

View File

@ -35,7 +35,7 @@
<div class="media-content">
<div class="content">
<p>
<strong class="is-capitalized">{{ o.title }}</strong> <small>{{ o.mime_type }}</small>
<strong class="is-capitalized">{{ o.title }}</strong> <small class="tag is-light">{{ o.mime_type }}</small>
<br>
{{ o.description }}
</p>
@ -96,7 +96,7 @@
<div class="media-content">
<div class="content">
<p>
<strong class="is-capitalized">{{ d.title }}</strong> <small>{{ d.mime_type }}</small>
<strong class="is-capitalized">{{ d.title }}</strong> <small class="tag is-light">{{ d.mime_type }}</small>
<br>
{{ d.description }}
</p>

View File

@ -30,6 +30,7 @@ class Collection extends Entity {
$filters_order,
$enable_cover_page,
$cover_page_id,
$header_image_id,
$moderators_ids;
/**
@ -323,8 +324,8 @@ class Collection extends Entity {
*
* @return string
*/
function get_columns() {
return $this->get_mapped_property( 'columns' );
function get_default_displayed_fields() {
return $this->get_mapped_property( 'default_displayed_fields' );
}
/**
@ -354,6 +355,15 @@ class Collection extends Entity {
return $this->get_mapped_property( 'enable_cover_page' );
}
/**
* Get Header Image ID attribute
*
* @return string
*/
function get_header_image_id() {
return $this->get_mapped_property( 'header_image_id' );
}
/**
* Return true if enabled cover page is set to yes
*
@ -503,12 +513,12 @@ class Collection extends Entity {
/**
* Set collection columns option
*
* @param [string] $value
* @param array $value
*
* @return void
*/
function set_columns( $value ) {
$this->set_mapped_property( 'columns', $value );
function set_default_displayed_fields( $value ) {
$this->set_mapped_property( 'default_displayed_fields', $value );
}
/**
@ -565,6 +575,17 @@ class Collection extends Entity {
function set_cover_page_id( $value ) {
$this->set_mapped_property( 'cover_page_id', $value );
}
/**
* Set Header Image ID
*
* @param [string] $value
*
* @return void
*/
function set_header_image_id( $value ) {
$this->set_mapped_property( 'header_image_id', $value );
}
/**
* Set collection moderators ids

View File

@ -189,7 +189,10 @@ class Entity {
}
}
$this->set_validated($is_valid);
if($is_valid){
$this->set_as_valid();
}
return $is_valid;
}

View File

@ -432,11 +432,15 @@ class Field extends Entity {
$is_valid = $fto->validate_options($this);
}
if (true === $is_valid)
return true;
if (true === $is_valid) {
$this->set_as_valid();
return true;
}
if (!is_array($is_valid))
throw new \Exception("Return of validate_options field type method should be an Array in case of error");
if (!is_array($is_valid)) {
throw new \Exception( "Return of validate_options field type method should be an Array in case of error" );
}
$this->add_error('field_type_options', $is_valid);

View File

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

View File

@ -370,7 +370,8 @@ class Item_Metadata_Entity extends Entity {
'key' => $this->field->get_id(),
'value' => $value
],
]
],
'post__not_in' => [$item->get_id()]
], $item->get_collection());
if ($test->have_posts()) {

View File

@ -388,6 +388,10 @@ class Item extends Entity {
}
}
if($is_valid){
$this->set_as_valid();
}
return $is_valid;
}

View File

@ -14,6 +14,7 @@ class Term extends Entity {
$parent,
$description,
$user,
$header_image_id,
$taxonomy;
@ -125,6 +126,15 @@ class Term extends Entity {
function get_taxonomy() {
return $this->get_mapped_property('taxonomy');
}
/**
* Get Header Image ID attribute
*
* @return string
*/
function get_header_image_id() {
return $this->get_mapped_property( 'header_image_id' );
}
// Setters
@ -173,6 +183,17 @@ class Term extends Entity {
$this->set_mapped_property('taxonomy', $value);
}
/**
* Set Header Image ID
*
* @param [string] $value
*
* @return void
*/
function set_header_image_id( $value ) {
$this->set_mapped_property( 'header_image_id', $value );
}
/**
*
@ -221,6 +242,7 @@ class Term extends Entity {
return false;
}
$this->set_as_valid();
return true;
}

View File

@ -59,7 +59,7 @@
return metadata.value;
}
}
return '';
return '';
}
},
methods: {
@ -67,13 +67,7 @@
this.isLoading = true;
let promise = null;
if ( this.type === 'Tainacan\\Field_Types\\Relationship' ) {
let collectionTarget = ( this.field_object && this.field_object.field_type_options.collection_id ) ? this.field_object.field_type_options.collection_id : this.collection_id;
promise = this.getValuesRelationship( collectionTarget );
} else {
promise = this.getValuesPlainText( this.field );
}
promise = this.getValuesPlainText( this.field );
promise.then(() => {
this.isLoading = false;
@ -105,4 +99,4 @@
}
}
}
</script>
</script>

View File

@ -122,7 +122,9 @@ class Collections extends Repository {
'default_displayed_fields' => [
'map' => 'meta',
'title' => __( 'Default Displayed Fields', 'tainacan' ),
'type' => 'string',
'type' => 'array/object/string',
'items' => [ 'type' => 'array/string/integer/object' ],
'default' => [],
'description' => __( 'List of collections property that will be displayed in the table view.', 'tainacan' ),
//'validation' => v::stringType(),
],
@ -166,6 +168,15 @@ class Collections extends Repository {
'on_error' => __('Invalid page', 'tainacan'),
//'validation' => v::numeric(),
'default' => ''
],
'header_image_id' => [
'map' => 'meta',
'title' => __('Header Image', 'tainacan'),
'type' => 'string',
'description'=> __('The image to be used in collection header', 'tainacan'),
'on_error' => __('Invalid image', 'tainacan'),
//'validation' => v::numeric(),
'default' => ''
],
'moderators_ids' => [
'map' => 'meta_multi',
@ -262,10 +273,22 @@ class Collections extends Repository {
*/
public function delete( $args ) {
if ( ! empty( $args[1] ) && $args[1] === true ) {
return new Entities\Collection( wp_delete_post( $args[0], $args[1] ) );
$deleted = new Entities\Collection( wp_delete_post( $args[0], $args[1] ) );
if($deleted) {
do_action( 'tainacan-deleted', $deleted, $is_update = false, $is_delete_permanently = true );
}
return $deleted;
}
return new Entities\Collection( wp_trash_post( $args[0] ) );
$trashed = new Entities\Collection( wp_trash_post( $args[0] ) );
if($trashed) {
do_action( 'tainacan-trashed', $trashed, $is_update = false, $is_delete_permanently = false );
}
return $trashed;
}
/**

View File

@ -430,8 +430,6 @@ class Fields extends Repository {
* @see \Tainacan\Repositories\Repository::insert()
*/
public function insert($field){
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
$this->pre_update_category_field($field);
$new_field = parent::insert($field);
@ -452,7 +450,14 @@ class Fields extends Repository {
public function delete($field_id){
$this->delete_category_field($field_id);
return new Entities\Field( wp_trash_post( $field_id ) );
$deleted = new Entities\Field( wp_trash_post( $field_id ) );
if($deleted) {
do_action( 'tainacan-deleted', $deleted, $is_update = false, $is_delete_permanently = true );
}
return $deleted;
}
/**

View File

@ -186,10 +186,24 @@ class Filters extends Repository {
*/
public function delete($args){
if(!empty($args[1]) && $args[1] === true){
return new Entities\Filter(wp_delete_post($args[0], $args[1]));
$deleted = new Entities\Filter(wp_delete_post($args[0], $args[1]));
if($deleted){
do_action('tainacan-deleted', $deleted, $is_update = false, $is_delete_permanently = true);
}
return $deleted;
}
return new Entities\Filter(wp_trash_post($args[0]));
$trashed = new Entities\Filter(wp_trash_post($args[0]));
if($trashed){
do_action('tainacan-trashed', $trashed, $is_update = false, $is_delete_permanently = false);
}
return $trashed;
}
public function update($object, $new_values = null){

View File

@ -13,18 +13,15 @@ class Items extends Repository {
private static $instance = null;
public static function get_instance()
{
if(!isset(self::$instance))
{
public static function get_instance() {
if(!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
protected function __construct()
{
protected function __construct() {
parent::__construct();
add_filter( 'posts_where', array(&$this, 'title_in_posts_where'), 10, 2 );
add_filter( 'posts_where', array(&$this, 'content_in_posts_where'), 10, 2 );
@ -167,108 +164,7 @@ class Items extends Repository {
}
public function insert( $item ) {
$is_update = false;
$diffs = [];
if ( $item->get_id() ) {
$old = $item->get_repository()->fetch( $item->get_id() );
if($old->get_status() === 'auto-draft') {
$is_update = false;
} else {
$is_update = true;
}
$diffs = $this->diff($old, $item);
}
$map = $this->get_map();
// get collection to determine post type
$collection = $item->get_collection();
if ( !$collection ) {
return false;
}
$cpt = $collection->get_db_identifier();
// iterate through the native post properties
foreach ( $map as $prop => $mapped ) {
if ( $mapped['map'] != 'meta' && $mapped['map'] != 'meta_multi' && $mapped['map'] != 'terms' ) {
$item->WP_Post->{$mapped['map']} = $item->get_mapped_property( $prop );
}
}
// save post and get its ID
$item->WP_Post->post_type = $cpt;
//$item->WP_Post->post_status = 'publish';
$id = wp_insert_post( $item->WP_Post );
$item->WP_Post = get_post( $id );
// Now run through properties stored as postmeta
foreach ( $map as $prop => $mapped ) {
if ( $mapped['map'] == 'meta' ) {
update_post_meta( $id, $prop, wp_slash( $item->get_mapped_property( $prop ) ) );
} elseif ( $mapped['map'] == 'meta_multi' ) {
$values = $item->get_mapped_property( $prop );
delete_post_meta( $id, $prop );
if ( is_array( $values ) ) {
foreach ( $values as $value ) {
add_post_meta( $id, $prop, wp_slash( $value ) );
}
}
}
}
if ( method_exists( $item, 'get_featured_img_id' ) ) {
if ( ! get_post_thumbnail_id( $item->WP_Post->ID ) ) {
// was added a thumbnail
$settled = set_post_thumbnail( $item->WP_Post, $item->get_featured_img_id( $item->WP_Post->ID ) );
if ( $settled ) {
$thumbnail_url = get_the_post_thumbnail_url( $item->WP_Post->ID );
$diffs['featured_image'] = [
'new' => $thumbnail_url,
'old' => '',
'diff_with_index' => 0,
];
}
} else {
// was update a thumbnail
$old_thumbnail = get_the_post_thumbnail_url( $item->WP_Post->ID );
$settled = set_post_thumbnail( $item->WP_Post, $item->get_featured_img_id( $item->WP_Post->ID ) );
if ( $settled ) {
$thumbnail_url = get_the_post_thumbnail_url( $item->WP_Post->ID );
$diffs['featured_image'] = [
'new' => $thumbnail_url,
'old' => $old_thumbnail,
'diff_with_index' => 0,
];
}
}
}
do_action( 'tainacan-insert', $item, $diffs, $is_update );
do_action( 'tainacan-insert-Item', $item );
// return a brand new object
return new Entities\Item( $item->WP_Post );
return parent::insert($item);
}
/**
@ -395,10 +291,23 @@ class Items extends Repository {
*/
public function delete( $args ) {
if ( ! empty( $args[1] ) && $args[1] === true ) {
return new Entities\Item( wp_delete_post( $args[0], $args[1] ) );
$deleted = new Entities\Item( wp_delete_post( $args[0], $args[1] ) );
if($deleted) {
do_action( 'tainacan-deleted', $deleted, $is_update = false, $is_delete_permanently = true );
}
return $deleted;
}
return new Entities\Item( wp_trash_post( $args[0] ) );
$trashed = new Entities\Item( wp_trash_post( $args[0] ) );
if($trashed) {
do_action( 'tainacan-trashed', $trashed, $is_update = false, $is_delete_permanently = false );
}
return $trashed;
}
/**

View File

@ -28,10 +28,12 @@ class Logs extends Repository {
protected function __construct() {
parent::__construct();
add_action( 'tainacan-insert', array( $this, 'insert_log' ), 10, 3 );
add_action( 'tainacan-insert', array( $this, 'insert_log' ), 10, 4 );
add_action( 'tainacan-deleted', array( $this, 'insert_log'), 10, 4 );
add_action( 'tainacan-trashed', array( $this, 'insert_log'), 10, 4 );
add_action( 'add_attachment', array( $this, 'prepare_attachment_log_before_insert' ), 10, 3 );
// add_action( 'attachment_updated', array( $this, 'prepare_attachment_log_before_insert' ), 10, 3);
add_action( 'add_attachment', array( $this, 'prepare_attachment_log_before_insert' ), 10 );
add_action( 'attachment_updated', array( $this, 'prepare_attachment_log_before_insert' ), 10, 3);
}
public function get_map() {
@ -263,6 +265,8 @@ class Logs extends Repository {
}
}
} else {
// TODO: Save a log when a attachment is updated
}
}
@ -270,16 +274,16 @@ class Logs extends Repository {
* Insert a log when a new entity is inserted
*
* @param Entity $new_value
* @param Entity $old_value
*
* @param array $diffs
* @param null $is_update
*
* @return Entities\Log new created log
*/
public function insert_log( $new_value, $diffs, $is_update = null ) {
public function insert_log( $new_value, $diffs = [], $is_update = null, $is_delete_permanently = null ) {
$msn = "";
$description = "";
// TODO: Continue with is_delete_permanently
if ( is_object( $new_value ) ) {
// do not log a log
if ( ( method_exists( $new_value, 'get_post_type' ) && $new_value->get_post_type() === 'tainacan-log' ) || $new_value->get_status() === 'auto-draft' ) {

View File

@ -108,6 +108,19 @@ abstract class Repository {
$obj->WP_Post->post_status = 'publish';
}
if( $obj instanceof Entities\Item ){
// get collection to determine post type
$collection = $obj->get_collection();
if ( !$collection ) {
return false;
}
$post_t = $collection->get_db_identifier();
$obj->WP_Post->post_type = $post_t;
}
// TODO verificar se salvou mesmo
$id = wp_insert_post( $obj->WP_Post );

View File

@ -193,22 +193,26 @@ class Taxonomies extends Repository {
return $unregistered;
}
$deleted = wp_delete_post($taxonomy_id, true);
$deleted = new Entities\Taxonomy(wp_delete_post($taxonomy_id, true));
if(!$deleted){
return $deleted;
}
return new Entities\Taxonomy($deleted);
do_action('tainacan-deleted', $deleted, $is_update = false, $is_delete_permanently = true);
return $deleted;
}
$trashed = wp_trash_post($taxonomy_id);
$trashed = new Entities\Taxonomy(wp_trash_post($taxonomy_id));
if(!$trashed){
return $trashed;
}
return new Entities\Taxonomy($trashed);
do_action('tainacan-trashed', $trashed, $diffs = [], $is_update = false, $is_delete_permanently = false );
return $trashed;
}

View File

@ -79,6 +79,15 @@ class Terms extends Repository {
'on_error' => __('The user is empty or invalid', 'tainacan'),
'default' => get_current_user_id(),
'validation' => v::numeric(),
],
'header_image_id' => [
'map' => 'termmeta',
'title' => __('Header Image', 'tainacan'),
'type' => 'string',
'description'=> __('The image to be used in term header', 'tainacan'),
'on_error' => __('Invalid image', 'tainacan'),
//'validation' => v::numeric(),
'default' => ''
],
'hide_empty' => [
'map' => 'hide_empty',
@ -225,7 +234,15 @@ class Terms extends Repository {
}
public function delete($args){
return wp_delete_term($args[0], $args[1]);
$deleted = wp_delete_term($args[0], $args[1]);
if($deleted) {
$deleted_term_tainacan = new Entities\Term($args[0], $args[1]);
do_action( 'tainacan-deleted', $deleted_term_tainacan, $is_update = false, $is_delete_permanently = true );
}
return $deleted;
}
public function register_post_type() { }

View File

@ -406,7 +406,13 @@ abstract class Importer {
// inserted the id on processed item with its index as array index
$this->processed_items[ $index ] = $item->get_id();
$Tainacan_Items->update( $item );
if($item->validate()) {
$Tainacan_Items->update( $item );
} else {
$this->add_log( 'error', 'Item ' . $index . ': ' ); // TODO add the $item->get_errors() array
return false;
}
return $item;
} else {
$this->add_log( 'error', 'Collection not set');

View File

@ -22,6 +22,7 @@ class Old_Tainacan extends Importer
public function fetch_from_remote( $url ){
$url_json = explode('/colecao/', $url)[0] . "/wp-json/tainacan/v1/collections";
$all_collections_info = wp_remote_get($url_json);
if(isset($all_collections_info['body']))
@ -54,19 +55,11 @@ class Old_Tainacan extends Importer
{
$items_array = json_decode($items['body']);
//Get Metatype
$meta_type = wp_remote_get($link."/metadata");
if(isset($meta_type['body']))
{
$meta_type_array = json_decode($meta_type['body']);
$file_info['items'] = $items_array;
$file_info['meta'] = $meta_type_array;
$file = fopen( $this->get_id().'.txt', 'w' );
fwrite( $file, serialize($items_array));
fclose( $file );
$file = fopen( $this->get_id().'.txt', 'w' );
fwrite( $file, serialize($file_info) );
fclose( $file );
return $this->set_file( $this->get_id().'.txt' );
}
return $this->set_file( $this->get_id().'.txt' );
}
}
}
@ -83,13 +76,13 @@ class Old_Tainacan extends Importer
$file = new \SplFileObject( $this->tmp_file, 'r' );
$file_content = unserialize($file->fread($file->getSize()));
$item = $file_content->items[0];
foreach($file_content['meta'] as $tab)
$fields = array_keys((array)$item->item);
foreach ($item->metadata as $metadata)
{
foreach($tab->{"tab-properties"} as $meta)
{
$fields[] = ['name' => $meta->name, 'type' => $meta->type];
}
$fields[] = ['name' => $metadata->name, 'type' => $metadata->type];
}
return $fields;
@ -113,27 +106,52 @@ class Old_Tainacan extends Importer
$file = new \SplFileObject( $this->tmp_file, 'r' );
$file_content = unserialize($file->fread($file->getSize()));
/*to fix this*/
$values = $file_content['items']->items[$index]->item;
if( count( $headers ) !== count( $values ) ){
return false;
}
foreach ($headers as $header) {
$processedItem[ $header['name'] ] = $values[ $header['name'] ];
$values = $file_content->items[$index];
foreach ($headers as $header)
{
if(isset($header['name']))
{
$item_index = $this->search_obj_in_array($values->metadata, $header['name']);
if(isset($values->metadata[ $item_index ]->values))
$processedItem[ $header['name'] ] = $values->metadata[ $item_index ]->values[0];
else $processedItem[ $header['name'] ] = '';
}
else
{
if($header === 'link')
{
$processedItem[$header] = $values->item->link[0]->href;
}
else
{
$processedItem[$header] = $values->item->{$header};
}
}
}
return $processedItem;
}
function create_fields_and_mapping() {
public function search_obj_in_array($array, $name)
{
foreach ($array as $index => $obj)
{
if(strcmp($obj->name, $name) === 0)
{
return $index;
}
}
return false;
}
public function create_fields_and_mapping()
{
$fields_repository = \Tainacan\Repositories\Fields::get_instance();
$file_fields = $this->get_fields();
/*$avoid = [
'ID',
$avoid = [
/*'ID',
'post_author',
'post_date',
'post_date_gmt',
@ -152,31 +170,55 @@ class Old_Tainacan extends Importer
'comment_count',
'filter',
'link',
'thumbnail'
];*/
'thumbnail'*/
];
foreach($file_fields as $index => $meta_info)
{
$newField = new \Tainacan\Entities\Field();
if(is_array($meta_info))
{
$meta_name = $meta_info['name'];
$type = $this->define_type($meta_info['type']);
}
else
{
$meta_name = $meta_info;
$type = 'Text';
}
$newField->set_name($meta_info['name']);
if(!in_array($meta_name, $avoid))
{
$newField = new \Tainacan\Entities\Field();
$type = 'Text';
$newField->set_name($meta_name);
$newField->set_field_type('Tainacan\Field_Types\\'.$type);
$newField->set_field_type('Tainacan\Field_Types\\'.$type);
$newField->set_collection($this->collection);
$newField->validate(); // there is no user input here, so we can be sure it will validate.
$newField->set_collection($this->collection);
$newField->validate(); // there is no user input here, so we can be sure it will validate.
$newField = $fields_repository->insert($newField);
$newField = $fields_repository->insert($newField);
$this->set_mapping([
$newField->get_id() => $file_fields[$index]
]);
$mapping[$newField->get_id()] = $file_fields[$index];
}
}
$this->set_mapping($mapping);
}
public function define_type($type)
{
$type = strtolower($type);
$tainacan_types = ['text', 'textarea', 'numerica', 'date'];
$types_to_work = ['item', 'tree'];
if(in_array($type, $tainacan_types))
{
$type = ucfirst($type);
}else $type = 'Text';
return $type;
}
/**
* Method implemented by the child importer class to return the number of items to be imported
@ -187,6 +229,6 @@ class Old_Tainacan extends Importer
$file = new \SplFileObject( $this->tmp_file, 'r' );
$file_content = unserialize($file->fread($file->getSize()));
return $this->total_items = $file_content['items']->found_items;
return $this->total_items = $file_content->found_items;
}
}

View File

@ -36,7 +36,8 @@ class Theme_Helper {
add_action('archive_template_hierarchy', array(&$this, 'items_template_hierachy'));
add_action('single_template_hierarchy', array(&$this, 'items_template_hierachy'));
add_filter('theme_mod_header_image', array(&$this, 'header_image'));
}
public function print_scripts() {
@ -78,6 +79,7 @@ class Theme_Helper {
$content = '';
// document
$content .= $item->get_document_html();
// metadata
$content .= $item->get_metadata_as_html();
@ -195,5 +197,30 @@ class Theme_Helper {
}
function header_image($image) {
$object = false;
if ($collection_id = tainacan_get_collection_id()) {
$object = \Tainacan\Repositories\Collections::get_instance()->fetch($collection_id);
} elseif ($term = tainacan_get_term()) {
$object = \Tainacan\Repositories\Terms::get_instance()->fetch($term->term_id, $term->taxonomy);
}
if (!$object)
return $image;
$header_image = $object->get_header_image_id();
if (is_numeric($header_image)) {
$src = wp_get_attachment_image_src($header_image, 'full');
if (is_array($src)) {
$image = $src[0];
}
}
return $image;
}
}

View File

@ -40,5 +40,20 @@ function tainacan_the_metadata($field = null, $hide_empty = true) {
* @uses get_post_type() WordPress function, which looks for the global $wp_query variable
*/
function tainacan_get_collection_id() {
return Repositories\Collections::get_instance()->get_id_by_db_identifier(get_post_type());
if ( is_post_type_archive() || is_single() ) {
return Repositories\Collections::get_instance()->get_id_by_db_identifier(get_post_type());
}
return false;
}
/**
* When visiting a term archive, returns the current term object
*
* @return false|\WP_Term
*/
function tainacan_get_term() {
if ( is_tax() ) {
return get_queried_object();
}
return false;
}

View File

@ -26,6 +26,8 @@ class Entity_Factory {
* @param array $args
* @param bool $is_validated_and_in_db
*
* @param bool $publish
*
* @return mixed
* @throws \ErrorException
*/

View File

@ -66,7 +66,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'values' => 'TestValues_exposers',
]);
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $item->get_id() . '/metadata/' . $field->get_id() );
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/' . $this->field->get_id() );
$request->set_body($item__metadata_json);
$response = $this->server->dispatch($request);
@ -75,13 +75,13 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$data = $response->get_data();
$this->assertEquals($item->get_id(), $data['item']['id']);
$this->assertEquals($this->item->get_id(), $data['item']['id']);
$this->assertEquals('TestValues_exposers', $data['value']);
$item_exposer_json = json_encode([
'exposer-map' => 'Value',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata/'. $field->get_id() );
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/'. $this->field->get_id() );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
@ -89,7 +89,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertEquals('TestValues_exposers', $data['teste_Expose']);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata' );
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
@ -112,7 +112,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'values' => 'TestValues_exposers',
]);
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $item->get_id() . '/metadata/' . $field->get_id() );
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/' . $this->field->get_id() );
$request->set_body($item__metadata_json);
$response = $this->server->dispatch($request);
@ -121,14 +121,14 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$data = $response->get_data();
$this->assertEquals($item->get_id(), $data['item']['id']);
$this->assertEquals($this->item->get_id(), $data['item']['id']);
$this->assertEquals('TestValues_exposers', $data['value']);
$item_exposer_json = json_encode([
'exposer-type' => 'Xml',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata/'. $field->get_id() );
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/'. $this->field->get_id() );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
@ -139,7 +139,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$item_exposer_json = json_encode([
'exposer-map' => 'Dublin Core',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata/'. $field->get_id() );
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/'. $this->field->get_id() );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
@ -150,7 +150,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'exposer-type' => 'Xml',
'exposer-map' => 'Dublin Core',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata' );
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
@ -177,7 +177,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$item_exposer_json = json_encode([
'exposer-type' => 'OAI-PMH',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata' );
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
@ -201,7 +201,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'exposer-type' => 'Html',
'exposer-map' => 'Value'
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata' );
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
@ -250,7 +250,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'values' => 'TestValues_exposers',
]);
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $item->get_id() . '/metadata/' . $field->get_id() );
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/' . $this->field->get_id() );
$request->set_body($item__metadata_json);
$response = $this->server->dispatch($request);
@ -260,7 +260,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$item_exposer_json = json_encode([
'exposer-type' => 'Csv',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata' );
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
@ -296,7 +296,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'values' => 'TestValues_exposers',
]);
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $item->get_id() . '/metadata/' . $field->get_id() );
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/' . $this->field->get_id() );
$request->set_body($item__metadata_json);
$response = $this->server->dispatch($request);
@ -305,7 +305,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$data = $response->get_data();
$this->assertEquals($item->get_id(), $data['item']['id']);
$this->assertEquals($this->item->get_id(), $data['item']['id']);
$this->assertEquals('TestValues_exposers', $data['value']);
$item2 = $this->tainacan_entity_factory->create_entity(
@ -313,7 +313,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
array(
'title' => 'item_teste_Expose2',
'description' => 'adasdasdsa2',
'collection' => $collection
'collection' => $this->collection
),
true,
true
@ -324,7 +324,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
array(
'title' => 'item_teste_Expose3',
'description' => 'adasdasdsa3',
'collection' => $collection
'collection' => $this->collection
),
true,
true
@ -334,7 +334,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'exposer-map' => 'Value',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/items/' . $item->get_id() );
$request = new \WP_REST_Request('GET', $this->namespace . '/items/' . $this->item->get_id() );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());

View File

@ -37,19 +37,20 @@ class ImporterTests extends TAINACAN_UnitTestCase {
$old_tainacan = new Importer\Old_Tainacan(true);
$id = $old_tainacan->get_id();
$_SESSION['tainacan_importer'][$id]->set_items_per_step(2);
$_SESSION['tainacan_importer'][$id]->set_items_per_step(50);
if(!copy('./tests/attachment/json_old_tainacan_base.txt', './tests/attachment/json_old_tainacan.txt'))
/*if(!copy('./tests/attachment/json_old_tainacan_base.txt', './tests/attachment/json_old_tainacan.txt'))
{
return false;
}
$_SESSION['tainacan_importer'][$id]->set_file( './tests/attachment/json_old_tainacan.txt' );
$_SESSION['tainacan_importer'][$id]->fetch_from_remote( 'http://localhost/colecao/colecao-to-import/' );
$_SESSION['tainacan_importer'][$id]->run();
}*/
public function test_file_old_tainacan () {
/*public function test_file_old_tainacan () {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
@ -72,7 +73,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
$this->assertTrue( isset( $_SESSION['tainacan_importer'][$id]->tmp_file ) );
$_SESSION['tainacan_importer'][$id]->run();
/*// count size of old tainacan file
$this->assertEquals( 5, $_SESSION['tainacan_importer'][$id]->get_total_items() );
// get fields to mapping
@ -119,8 +120,8 @@ class ImporterTests extends TAINACAN_UnitTestCase {
$items = $Tainacan_Items->fetch( [], $collection, 'OBJECT' );
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_total_items(), count( $items ) );*/
}
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_total_items(), count( $items ) );
}*/
/**
* @group importer
*/
@ -151,14 +152,14 @@ class ImporterTests extends TAINACAN_UnitTestCase {
public function test_file_csv () {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
$file_name = 'demosaved.csv';
$csv_importer = new Importer\CSV();
$id = $csv_importer->get_id();
$_SESSION['tainacan_importer'][$id]->set_items_per_step(2);
// open the file "demosaved.csv" for writing
$file = fopen('demosaved.csv', 'w');
$file = fopen($file_name, 'w');
// save the column headers
fputcsv($file, array('Column 1', 'Column 2', 'Column 3', 'Column 4', 'Column 5'));
@ -180,7 +181,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
// Close the file
fclose($file);
$_SESSION['tainacan_importer'][$id]->set_file( 'demosaved.csv' );
$_SESSION['tainacan_importer'][$id]->set_file( $file_name );
// file isset on importer
$this->assertTrue( isset( $_SESSION['tainacan_importer'][$id]->tmp_file ) );

View File

@ -149,8 +149,6 @@ class Item_Metadata extends TAINACAN_UnitTestCase {
true
);
$test = $Tainacan_Fields->fetch($field->get_id());
$i = $this->tainacan_entity_factory->create_entity(
'item',
array(
@ -161,14 +159,23 @@ class Item_Metadata extends TAINACAN_UnitTestCase {
),
true
);
$i2 = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'other item',
'description' => 'adasdasdsa',
'collection' => $collection,
'status' => 'publish'
),
true
);
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$item = $Tainacan_Items->fetch($i->get_id());
$value = 'teste_val';
$item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($item, $test);
$item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($i, $field);
$item_metadata->set_value($value);
$this->assertTrue($item_metadata->validate());
@ -176,10 +183,13 @@ class Item_Metadata extends TAINACAN_UnitTestCase {
$item_metadata->validate();
$item_metadata = $Tainacan_Item_Metadata->insert($item_metadata);
$n_item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($item, $test);
$n_item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($i, $field);
$n_item_metadata->set_value($value);
$this->assertTrue($n_item_metadata->validate(), 'trying to validate the same item with same value should be ok');
$this->assertFalse($n_item_metadata->validate());
$n_item_metadata2 = new \Tainacan\Entities\Item_Metadata_Entity($i2, $field);
$n_item_metadata2->set_value($value);
$this->assertFalse($n_item_metadata2->validate(), 'Collection key should not validate another item metadatada with the same value');
}
function teste_fetch(){