Merge branch 'develop' into feature/facets_ES

This commit is contained in:
vnmedeiros 2019-04-16 11:34:23 -03:00
commit 55e604bc40
78 changed files with 3383 additions and 380 deletions

45
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,45 @@
---
name: Bug report
about: Is something not working as expected? Report it here
title: ''
labels: bug
assignees: ''
---
**Bug description**
What is happening?
**How to reproduce such bug**
Use the following template to create a step-by-step guide:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
What did you expect to happen?
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,24 @@
---
name: Feature request
about: Suggest a new feature to our Tainacan devs! 🎉
title: ''
labels: ''
assignees: ''
---
**Context and motivation**
Why do you think this feature is needed? Who would benefit from it?
**Ideal solution**
What would you describe as the best solution to implement such feature?
**Alternative solutions**
Is there any other way to implement it?
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,17 +1,49 @@
[![Build Status](https://travis-ci.org/tainacan/tainacan.svg?branch=develop)](https://travis-ci.org/tainacan/tainacan) [![Waffle.io - Columns and their card count](https://badge.waffle.io/tainacan/tainacan.svg?columns=In%20Progress)](https://waffle.io/tainacan/tainacan)
[![Build Status](https://travis-ci.org/tainacan/tainacan.svg?branch=develop)](https://travis-ci.org/tainacan/tainacan)
# Tainacan
- Tainacan's [plugin](https://wordpress.org/plugins/tainacan/) and [theme](https://wordpress.org/themes/tainacan-interface/) on WordPress.org
- [Access our homepage](http://tainacan.org)
- [Read our official documentation](https://wiki.tainacan.org/)
- [Explore our blog](http://tainacan.org/blog/)
- [Join our mailing list](https://lists.riseup.net/www/info/tainacan)
- [Follow us on Twitter](https://twitter.com/tainacan_l3p)
** This is the development repository of a new version of Tainacan. If you are looking for the current stable version, please visit http://github.com/medialab-ufg/tainacan. **
### What is Tainacan?
Tainacan is a WordPress plugin to build digital repositories. Manage and publish digital collections of any kind.
In this repository, we are building a new version of tainacan. The package will be composed of a WordPress plugin (this repository) and a WordPress Theme. More details of the architecture will be added here soon.
[![Screenshot](https://user-images.githubusercontent.com/29989176/54926885-f8cf5b80-4eef-11e9-870f-92b264f13dea.gif)][youtube_demo]
We plan to mantain this repository well documented to encourage early testers and contributors, so feel free to try it.
[youtube_demo]: https://www.youtube.com/watch?v=6q42dlcwW5g
Get to know Tainacan with our [introduction video](https://www.youtube.com/watch?v=6q42dlcwW5g).
First, get to know the [key concepts](docs/key-concepts.md) of tainacan and what it does. After that you may want to learn [how to set up your local enviroment](docs/setup-local.md).
Tainacan is a software solution for building, managing and publishing digital repositories of any kind on WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional repository platform. It is composed of a WordPress plugin, which is being developed on this repository, and an optional [companion WordPress theme](https://github.com/tainacan/tainacan-theme) especially designed to produce beautiful digital exhibits. [Try it out!](http://demo.tainacan.org/)
We are still in early stages of development, and any help, feedback or contribution is welcome. Please drop us a line opening an issue or via one of our communication channels:
### Features
* twitter: @tainacan_l3p
**Easy installation**. As a WordPress plugin, Tainacan can be easily installed on and integrated to an existing WordPress website.
**Metadata and filters**. Use a metadata standard or choose whatever set of metadata you want to describe the items in your collections. You can choose which metadata will be used as a filter when browsing the collection.
**Faceted search**. Browse your collection (and let the public browse it) using a faceted search interface with the filters you have chosen.
**Manage taxonomies**. Manage vocabularies that can be used accross all your collections.
**Themes**. Tainacan [has its own default theme](https://wordpress.org/themes/tainacan-interface/), which helps you present your collections in a beautiful and effective way as it is developed to incorporate all of Tainacan functionalities. However, it will also work with any WordPress theme. For developers, it will be easy to add Tainacan specific features to an existing theme.
**API and interoperability**. Tainacan implements a RESTful API (read and write) to allow other applications to interact with your repository. Expose you collection in different formats, such as JSON, JSON-LD and OAI-PMH. If your collection uses a custom standard, you can map it to well-known stardards such as DublinCore.
### Showcases
Check out the digital exhibits from [Museu do Índio](http://tainacan.museudoindio.gov.br/) and [Museu Histórico Nacional](http://mhn.acervos.museus.gov.br/) to see Tainacan in action!
### Support
In addition to [our documentation](https://wiki.tainacan.org/) and [instructional videos](https://youtu.be/oEl9bWe_rWI), we provide technical support on our [mailing list](https://lists.riseup.net/www/info/tainacan) in English, Portuguese and Spanish. You are welcome to send all of your questions!
### Contributing
Tainacan is a free, open source software licensed under **GPLv3**. Contributions to the codebase will abide to the same license; other contributions may be under additional or other terms.
To contribute with our project, you can report bugs and other issues, or suggest new features. You are also free to submit pull requests or translate Tainacan to multiple languages. If you are interested in contributing, you can get started by reading our [contribution guidelines](docs/CONTRIBUTING.md).
### Acknowledgements
Tainacan is the results of continuous efforts from developers, researchers, policy makers and GLAMs in Brazil. We are eternally grateful for all of [our amazing contributors](https://github.com/tainacan/tainacan/graphs/contributors)!

23
docs/CONTRIBUTING.md Normal file
View File

@ -0,0 +1,23 @@
## Contribution guidelines
Interested in contributing to Tainacan? That's awesome! :muscle: In this page, we'll talk about paths of contribution and what we consider a quality contribution.
### Our language policy
While Tainacan is a Brazilian project, we have adopted English as our primary language on development matters. Writing comments in Portuguese on [issues](https://github.com/tainacan/tainacan/issues) and [pull requests](https://github.com/tainacan/tainacan/pulls) is allowed as long as you provide an English translation of your comments. Writing comments in Portuguese on commits is expressively prohibited. Comments on the codebase and variable names should also be written in English only.
### Thinking about how you can contribute
Ask yourself the following questions: do you work, directly or indirectly, with cultural preservation? If yes, what do you do? If not, are you just a curious person just excited about it? What kind of skills do you have? Is there something you find fun to do you think you can shape as a contribution to Tainacan?
Free and open source projects offer a diversity of contributions options that go from direct involvement with the development of a software (submiting patches to eliminate a bug, implementing new features, creating new tests) to works related to localization (translating the software interface), design (creative works), user experience (testing new iterations of Tainacan and reporting issues), documentation (contributing to our wiki with new articles or improving existing ones) and communication (creating videos about Tainacan, giving talks mentioning it). Here, we'll talk about in particular about contributions to this repository.
### Issue system
An issue is a thread within the project's GitHub repository focused on debating bugs, feature requests or errors one may stumble upon. To gather as much information as possible and organize discussions to be clearer and more searchable, this repository has a few templates for the most common issues:
#### Bug report
If something is not working properly on Tainacan, use this template.
#### Feature request
If you have any feature ideas you would like to suggest to our developers, use this template.
A great issue is one that includes a concise description of errors you are stumbling upon along with crucial information such as which version of Tainacan you are using, which web browser, or which WordPress version. It's also important to search our repository for duplicates—and if you find one, opt to participate in the original discussion adding new information instead of creating your own. That will help contributors and users to keep track of a specific subject more easily.

View File

@ -0,0 +1,248 @@
# Creating a custom Metadata type
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;
Each metadata type object have its own settings and web component that will be used to render the interface.
Developers can create custom Metadata Types via plugins. This article shows how to do this.
A Metadata Type is composed of a simple PHP class and a Vue Web Component.
## PHP Class
### Registering your Metadata Type
First of all, you have to register you Metadata type class. You do this by calling the `register_metadata_type` method of the `Metadata` Repository:
```PHP
add_action('init', 'my_custom_mt_registration');
function my_custom_mt_registration() {
$Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance();
$Tainacan_Metadata->register_metadata_type('MyCustomMetadataTypeClass');
}
```
Now you have to create the class you just register, and use its constructor to set the basic features of you Metadata Type:
```PHP
class MyCustomMetadataTypeClass {
public function __construct() {
parent::__construct();
$this->set_name( __('My Custom Metadata Type', 'my-domain') );
$this->set_description( __('My Custom Metadata Type', 'my-domain') );
$this->set_primitive_type('string');
$this->set_component('my-custom-component');
}
}
```
These are the basic methods you have to call to set up you MT:
* **set_name(string $name)** - Sets the name of the Metadata type. This is the name the user will see in the front end and should be internationalized.
* **set_description(string $name)** - Sets the description of the Metadata type. This is the text the user will see in the front end and should be internationalized.
* **set_primitive(string $type)** - Inform what is the raw type of data that will be stored. This is used mainly by Filter Types to decide what kind of Filters will be available for each Metadata Type. Current used primitive types are: string, date, float, item, term and long_string (you can create new ones if you want, just note that not Filter Types will be available to them)
set_preview_template
You can also set a HTML preview of your Metadata Type to help users visualize how it works. This will be displayed in the Metadata configuration screen, when the user click on the "?" icon of a Metadata Type.
* **set_preview_template(string $template)** - The HTML code that previwes the plugin. Use [Buefy](https://buefy.github.io/) and [Bulma](http://bulma.io/) classes.
### Metadata type Options
When you register a new Metadata Type, it will be automatically added as an option in the Metadata configuration screen. It will also have the default metadata configuration form, where you set whether the metadata is required or not, accept multiple values or not, and so on.
However, you metadata type may have specific options you want to give to the users. For example: In the Selectbox Metadata type, you have the ability to set what will be the options in your Selectbox.
In order to do this, you have to declare what are the options your metadata type has, and prepare another web component to be rendered in the metadata form:
```PHP
class MyCustomMetadataTypeClass {
public function __construct() {
parent::__construct();
$this->set_name( __('My Custom Metadata Type', 'my-domain') );
$this->set_description( __('My Custom Metadata Type', 'my-domain') );
$this->set_primitive_type('string');
$this->set_component('my-custom-component');
// custom options
$this->set_form_component('my-custom-form-component');
$this->set_default_options([
'my_option_1' => 'value 1',
'my_option_2' => 'value 2'
]);
}
}
```
Optionally you can implement `validate_options` method to validate the form before it gets saved:
```PHP
class MyCustomMetadataTypeClass {
public function __construct() {
parent::__construct();
$this->set_name( __('My Custom Metadata Type', 'my-domain') );
$this->set_description( __('My Custom Metadata Type', 'my-domain') );
$this->set_primitive_type('string');
$this->set_component('my-custom-component');
// custom options
$this->set_form_component('my-custom-form-component');
$this->set_default_options([
'my_option_1' => 'value 1',
'my_option_2' => 'value 2'
]);
}
public function validate_options( Metadatum $metadatum ) {
$option1 = $this->get_option('my_option_1');
if ($option1) { // some condition
return true; // validated!
} else {
return ['my_option_1' => __('This option is invald', 'my-domain')];
}
}
}
```
`validate_options` is expected to return `true` if valid, and an array where the keys are the option name and the values are the error messages.
### Additional Methods
There are few other methods you can implement that can change the items interact with metadata depending on the metadata type:
#### **validate( Item_Metadata_Entity $item_metadata)**
This method will override the validation of the Item Metadata Entity, which means every time Tainacan saves a value for a metadata of this type, it will call this method. For example, the Date Metadata Type override this method to make sure the date is in the correct format:
```PHP
public function validate( Item_Metadata_Entity $item_metadata) {
$value = $item_metadata->get_value();
$format = 'Y-m-d';
if (is_array($value)) {
foreach ($value as $date_value) {
$d = \DateTime::createFromFormat($format, $date_value);
if (!$d || $d->format($format) !== $date_value) {
$this->add_error(
sprintf(
__('Invalid date format. Expected format is YYYY-MM-DD, got %s.', 'tainacan'),
$date_value
)
);
return false;
}
}
return True;
}
$d = \DateTime::createFromFormat($format, $value);
if (!$d || $d->format($format) !== $value) {
$this->add_error(
sprintf(
__('Invalid date format. Expected format is YYYY-MM-DD, got %s.', 'tainacan'),
$value
)
);
return false;
}
return true;
}
```
Note that it checks whether the value is a string (single value) or an array (multiple values).
#### **get_value_as_html( Item_Metadata_Entity $item_metadata)**
This method will change the way a value is converted to HTML for metadata of this metadata type. For example, Taxonomy and Relationship Metadata Type use this to add links to the related term/item in the HTML output.
## Creating Vue Web Component
*TODO: explain how to load the web component code.*
The Vue component is the chunk that will be rendered inside the Item Edition form so the user can edit it's metadata of your custom type.
As in any Vue component, you should provide a `template` with it's HTML content, a `script` with it's logic and optionally a `style`. Bellow are the template and script for the Selectbox metadata type:
```html
<template>
<b-input
:disabled="disabled"
:class="{'has-content': inputValue !== undefined && inputValue !== ''}"
:id="id"
type="number"
:value="inputValue"
step="0.01"
@blur="onBlur"
@change="onBlur"
@input="onInput($event)"/>
</template>
```
```javascript
<script>
export default {
created(){
if( this.value )
this.inputValue = this.value;
},
data() {
return {
inputValue: ''
}
},
props: {
id: '',
metadatum: {
type: Object
},
value: [String, Number, Array],
disabled: false,
},
methods: {
onBlur() {
this.$emit('blur');
},
onInput($event) {
this.inputValue = $event;
this.$emit('input', this.inputValue);
}
}
}
</script>
```
Notice first the "props" on the component. They are passed to every metadata:
- `metadadum` is the metadatum object itself, wich also contains the `metadata_type_options`;
- `value` is the value used for binding whatever is the content of this metadatum;
- `id` is the metadatum id;
- `disabled` is a boolean handled by the Item's form, which can be used to disable any inner component in case the options are not loaded and other situations that might be desired;
The "data" here has only a copy of the input value, passed during the `created()` lifecycle. Props are usualy not to be modified so we use this as an internal variable.
The "methods" here simply delegate the blur and input events to the default parent component, which is responsible for passing this values to the Item's form. **Attention: all metadatum component must emit an input value, passing the updated value that they received from the props**.
In the above example, a custom component from [Buefy](https://buefy.github.io/), `b-input` is used. You can use any javascript available from your plugin here, or just try out theirs, as it's already loaded on Tainacan's plugin. The styling also come from this library, inheriting [Bulma](http://bulma.io/), and it's recommended the use of their classes as most are overrided by Tainacan stylesheets.

View File

@ -8,7 +8,7 @@
},
"dependencies": {
"axios": "^0.18.0",
"buefy": "^0.7.3",
"buefy": "^0.7.4",
"bulma": "^0.7.4",
"mdi": "^2.2.43",
"moment": "^2.22.2",

View File

@ -13,8 +13,15 @@
<button
class="is-hidden-mobile"
id="menu-compress-button"
@click="isMenuCompressed = !isMenuCompressed">
<span class="icon">
@click="isMenuCompressed = !isMenuCompressed">
<span
v-tooltip="{
content: $i18n.get('label_shrink_menu'),
autoHide: true,
placement: 'auto-end',
classes: ['tooltip', 'repository-tooltip']
}"
class="icon">
<i
:class="{ 'tainacan-icon-arrowleft' : !isMenuCompressed, 'tainacan-icon-arrowright' : isMenuCompressed }"
class="tainacan-icon tainacan-icon-20px"/>

View File

@ -77,7 +77,7 @@ class Admin {
global $TAINACAN_BASE_URL;
// wp_enqueue_style( 'style', $TAINACAN_BASE_URL . '/assets/css/fonts/materialdesignicons.css' );
wp_enqueue_style( 'style', $TAINACAN_BASE_URL . '/assets/css/fonts/tainacanicons.css' );
wp_enqueue_style( 'tainacan-fonts', $TAINACAN_BASE_URL . '/assets/css/fonts/tainacanicons.css' );
wp_enqueue_script('underscore', includes_url('js') . '/underscore.min.js' );
}

View File

@ -129,7 +129,13 @@
@click="removeThis(searchCriterion)"
:class="{'has-text-blue4': isHeader, 'has-text-secondary': !isHeader,}"
class="button is-white is-pulled-right">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('remove_search_criterion'),
autoHide: true,
placement: 'auto-end'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-close"/>
</span>
</button>

View File

@ -173,7 +173,13 @@
v-if="!bulkEditionProcedures[criterion].isDone && !bulkEditionProcedures[criterion].isExecuting"
@click="removeThis(criterion)"
class="button is-white is-pulled-right">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('remove_search_criterion'),
autoHide: true,
placement: 'auto-end'
}"
class="icon">
<i class="has-text-gray4 tainacan-icon tainacan-icon-20px tainacan-icon-cancel"/>
</span>
</button>
@ -248,7 +254,13 @@
bulkEditionProcedures[criterion].action"
@click="executeBulkEditionProcedure(criterion)"
class="button is-white is-pulled-right">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_apply_changes'),
autoHide: true,
placement: 'auto-end'
}"
class="icon">
<i class="has-text-gray4 tainacan-icon tainacan-icon-20px tainacan-icon-play"/>
</span>
</button>
@ -563,8 +575,7 @@
}
.this-tainacan-modal-content {
border-radius: 10px;
min-height: 400px;
min-height: 300px;
}
.this-tainacan-modal-content .form-submit {

View File

@ -68,7 +68,13 @@
id="button-edit-thumbnail"
:aria-label="$i18n.get('label_button_edit_thumb')"
@click.prevent="thumbnailMediaFrame.openFrame($event)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
@ -77,7 +83,13 @@
id="button-delete-header-image"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteThumbnail()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>
@ -125,7 +137,13 @@
<a
target="_blank"
@click.prevent="removeCoverPage()">
<span class="icon is-small">
<span
v-tooltip="{
content: $i18n.get('remove_value'),
autoHide: true,
placement: 'bottom'
}"
class="icon is-small">
<i class="tainacan-icon tainacan-icon-close"/>
</span>
</a>
@ -137,7 +155,13 @@
<a
target="_blank"
:href="coverPage.link">
<span class="icon is-small">
<span
v-tooltip="{
content: $i18n.get('see'),
autoHide: true,
placement: 'bottom'
}"
class="icon is-small">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-see"/>
</span>
</a>
@ -145,7 +169,13 @@
<a
target="blank"
:href="coverPageEditPath">
<span class="icon is-small">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon is-small">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
@ -298,7 +328,13 @@
id="button-edit-header-image"
:aria-label="$i18n.get('label_button_edit_header_image')"
@click="headerImageMediaFrame.openFrame($event)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
@ -307,7 +343,13 @@
id="button-delete-header-image"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteHeaderImage()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>

View File

@ -113,7 +113,13 @@
class="button is-white is-pulled-right"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent="showEditMaxOptions = true">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-edit has-text-secondary"/>
</span>
</button>
@ -129,7 +135,13 @@
<button
@click.prevent="showEditMaxOptions = false"
class="button is-white is-pulled-right">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('close'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-close has-text-secondary"/>
</span>
</button>

View File

@ -89,7 +89,14 @@
<a
target="_blank"
@click.prevent="importerFile = undefined">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('remove_value'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', 'repository-tooltip'],
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-close"/>
</span>
</a>

View File

@ -106,7 +106,16 @@
</span>
<span
v-if="item.document != '' && item.document_type != 'empty'"
class="icon has-text-success">
class="icon has-text-success"
v-tooltip="{
delay: {
show: 500,
hide: 300,
},
content: $i18n.get('label_document_uploaded'),
autoHide: false,
placement: 'auto-start'
}">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-approvedcircle" />
</span>
</div>

View File

@ -71,7 +71,13 @@
id="button-edit-document"
:aria-label="$i18n.get('label_button_edit_document')"
@click.prevent="setFileDocument($event)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
@ -81,7 +87,13 @@
id="button-delete-document"
:aria-label="$i18n.get('label_button_delete_document')"
@click.prevent="removeDocument()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>
@ -95,7 +107,13 @@
:aria-label="$i18n.get('label_button_edit_document')"
id="button-edit-document"
@click.prevent="setTextDocument()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
@ -105,7 +123,13 @@
:aria-label="$i18n.get('label_button_delete_document')"
id="button-delete-document"
@click.prevent="removeDocument()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>
@ -120,7 +144,13 @@
:aria-label="$i18n.get('label_button_edit_document')"
id="button-edit-document"
@click.prevent="setURLDocument()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
@ -130,7 +160,13 @@
:aria-label="$i18n.get('label_button_delete_document')"
id="button-delete-document"
@click.prevent="removeDocument()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>
@ -274,7 +310,13 @@
id="button-edit-thumbnail"
:aria-label="$i18n.get('label_button_edit_thumb')"
@click.prevent="thumbnailMediaFrame.openFrame($event)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
@ -284,7 +326,13 @@
class="button is-rounded is-secondary"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteThumbnail()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>
@ -335,6 +383,11 @@
<span class="file-item-control">
<a
@click="deleteAttachment(attachment)"
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-delete"/>
</a>

View File

@ -167,8 +167,14 @@
type="button"
@click="cancelBack">{{ $i18n.get('cancel') }}</button>
</div>
<p
v-if="updatedAt != undefined"
class="updated-at">
{{ ($i18n.get('info_updated_at') + ' ' + updatedAt) }}
</p>
<div class="control">
<button
:class="{ 'is-loading': isLoadingTaxonomy }"
id="button-submit-taxonomy-creation"
@click.prevent="onSubmit"
class="button is-success">{{ $i18n.get('save') }}</button>
@ -234,7 +240,8 @@
wpPostTypes: tainacan_plugin.wp_post_types,
editFormErrors: {},
formErrorMessage: '',
entityName: 'taxonomy'
entityName: 'taxonomy',
updatedAt: undefined
}
},
components: {
@ -338,7 +345,9 @@
this.formErrorMessage = '';
this.editFormErrors = {};
this.$router.push(this.$routerHelper.getTaxonomiesPath());
// Updates saved at message
let now = new Date();
this.updatedAt = now.toLocaleString();
})
.catch((errors) => {
for (let error of errors.errors) {
@ -486,5 +495,13 @@
.tainacan-form .column:last-of-type {
padding-left: 0;
}
.form-submit {
align-items: center;
}
.updated-at {
margin: 0 1rem 0 auto;
color: #555758;
font-style: italic;
}
</style>

View File

@ -59,7 +59,14 @@
id="button-edit-header"
:aria-label="$i18n.get('label_button_edit_header_image')"
@click="headerImageMediaFrame.openFrame($event)">
<span class="icon is-small">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon is-small">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
@ -68,7 +75,14 @@
id="button-delete-header"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteHeaderImage()">
<span class="icon is-small">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon is-small">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>

View File

@ -40,6 +40,7 @@
},
content: activity.title,
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}">
{{ activity.title }}
@ -59,6 +60,7 @@
},
content: activity.user_name,
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-html="activity.user_name"/>
@ -77,6 +79,7 @@
},
content: activity.log_date,
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-html="activity.log_date"/>

View File

@ -25,12 +25,24 @@
:class="{'is-disabled': isEditingTerm}">
<a
@click.prevent="editTerm()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
<a @click.prevent="tryToRemoveTerm()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-delete"/>
</span>
</a>

View File

@ -20,7 +20,13 @@
tag="a"
:to="{ path: $routerHelper.getNewCollectionPath() }"
:aria-label="$i18n.get('label_collection_items')">
<span class="icon is-medium">
<span
v-tooltip="{
content: $i18n.get('label_collection_items'),
autoHide: true,
placement: 'auto'
}"
class="icon is-medium">
<i class="tainacan-icon tainacan-icon-36px tainacan-icon-items"/>
</span>
<span class="menu-text">{{ $i18n.get('items') }}</span>
@ -31,7 +37,13 @@
tag="a"
:to="{ path: $routerHelper.getNewCollectionPath() }"
:aria-label="$i18n.get('label_collection_metadata')">
<span class="icon is-medium">
<span
v-tooltip="{
content: $i18n.get('label_collection_metadata'),
autoHide: true,
placement: 'auto'
}"
class="icon is-medium">
<i class="tainacan-icon tainacan-icon-36px tainacan-icon-metadata"/>
</span>
<span class="menu-text">{{ $i18n.getFrom('metadata', 'name') }}</span>
@ -42,7 +54,13 @@
tag="a"
:to="{ path: $routerHelper.getNewCollectionPath() }"
:aria-label="$i18n.get('label_collection_filters')">
<span class="icon is-medium">
<span
v-tooltip="{
content: $i18n.get('label_collection_filters'),
autoHide: true,
placement: 'auto'
}"
class="icon is-medium">
<i class="tainacan-icon tainacan-icon-36px tainacan-icon-filters"/>
</span>
<span class="menu-text">{{ $i18n.getFrom('filters', 'name') }}</span>

View File

@ -163,6 +163,7 @@
},
content: collection.name,
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}">
{{ collection.name }}</p>
@ -182,6 +183,7 @@
},
content: (collection.description != undefined && collection.description != '') ? collection.description : `<span class='has-text-gray is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`,
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-html="(collection.description != undefined && collection.description != '') ? collection.description : `<span class='has-text-gray is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`"/>
@ -201,6 +203,7 @@
},
content: collection.creation_date,
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-html="collection.creation_date" />
@ -220,6 +223,7 @@
},
content: collection.author_name,
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-html="collection.author_name" />
@ -240,6 +244,7 @@
},
content: getTotalItems(collection.total_items),
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-html="getTotalItems(collection.total_items)" />
@ -255,7 +260,14 @@
v-if="collection.current_user_can_edit"
:aria-label="$i18n.getFrom('collections','edit_item')"
@click.prevent.stop="goToCollectionEditPage(collection.id)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-settings"/>
</span>
</a>
@ -264,7 +276,14 @@
v-if="collection.current_user_can_delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneCollection(collection.id)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="tainacan-icon tainacan-icon-20px"/>

View File

@ -58,18 +58,31 @@
<div class="handle">
<span
v-if="!(isSelectingFilterType || filter.id == undefined || openedFilterId != '' || choosenMetadatum.name == filter.name || isUpdatingFiltersOrder == true || isRepositoryLevel)"
v-tooltip="{
content: $i18n.get('instruction_drag_and_drop_filter_sort'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon grip-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-drag"/>
</span>
<span class="icon icon-level-identifier">
<span
v-tooltip="{
content: filter.collection_id != collectionId ? $i18n.get('label_repository_filter') : $i18n.get('label_collection_filter'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon icon-level-identifier">
<i
:class="{
'tainacan-icon-collections': filter.collection_id == collectionId,
'tainacan-icon-repository': filter.collection_id != collectionId,
'has-text-turquoise5': filter.enabled && filter.collection_id == collectionId,
'has-text-blue5': filter.enabled && filter.collection_id != collectionId,
'has-text-gray3': !filter.enabled
}"
'tainacan-icon-collections': filter.collection_id == collectionId,
'tainacan-icon-repository': filter.collection_id != collectionId,
'has-text-turquoise5': filter.enabled && filter.collection_id == collectionId,
'has-text-blue5': filter.enabled && filter.collection_id != collectionId,
'has-text-gray3': !filter.enabled
}"
class="tainacan-icon" />
</span>
<span
@ -102,14 +115,28 @@
<a
:style="{ visibility: filter.collection_id != collectionId && !isRepositoryLevel? 'hidden' : 'visible' }"
@click.prevent="editFilter(filter)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
<a
:style="{ visibility: filter.collection_id != collectionId && !isRepositoryLevel ? 'hidden' : 'visible' }"
@click.prevent="removeFilter(filter)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-delete"/>
</span>
</a>
@ -151,12 +178,29 @@
v-for="(metadatum, index) in availableMetadata"
:key="index"
@click.prevent="addMetadatumViaButton(metadatum, index)">
<span class="icon grip-icon">
<span
v-tooltip="{
content: $i18n.get('instruction_click_or_drag_filter_create'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon grip-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-drag"/>
</span>
<span class="icon icon-level-identifier">
<span
v-tooltip="{
content: isRepositoryLevel || metadatum.collection_id != collectionId ? $i18n.get('label_repository_filter') : $i18n.get('label_collection_filter'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon icon-level-identifier">
<i
:class="{ 'tainacan-icon-collections has-text-turquoise5': metadatum.collection_id == collectionId && !isRepositoryLevel, 'tainacan-icon-repository has-text-blue5': isRepositoryLevel || metadatum.collection_id != collectionId }"
:class="{
'tainacan-icon-collections has-text-turquoise5': metadatum.collection_id == collectionId && !isRepositoryLevel,
'tainacan-icon-repository has-text-blue5': isRepositoryLevel || metadatum.collection_id != collectionId
}"
class="tainacan-icon" />
</span>
<span class="metadatum-name">{{ metadatum.name }}</span>

View File

@ -184,7 +184,13 @@
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
@ -192,7 +198,13 @@
:aria-lavel="$i18n.get('label_button_untrash')"
@click.prevent.stop="untrashOneItem(item.id)"
v-if="isOnTrash">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_recover_from_trash'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-undo"/>
</span>
</a>
@ -201,7 +213,13 @@
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<span class="icon">
<span
v-tooltip="{
content: isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('delete'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
@ -278,7 +296,13 @@
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
@ -286,7 +310,13 @@
:aria-lavel="$i18n.get('label_button_untrash')"
@click.prevent.stop="untrashOneItem(item.id)"
v-if="isOnTrash">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_recover_from_trash'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-undo"/>
</span>
</a>
@ -295,7 +325,13 @@
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<span class="icon">
<span
v-tooltip="{
content: isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('delete'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
@ -358,7 +394,13 @@
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
@ -366,7 +408,13 @@
:aria-lavel="$i18n.get('label_button_untrash')"
@click.prevent.stop="untrashOneItem(item.id)"
v-if="isOnTrash">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_recover_from_trash'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-undo"/>
</span>
</a>
@ -375,7 +423,13 @@
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<span class="icon">
<span
v-tooltip="{
content: isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('delete'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
@ -528,7 +582,13 @@
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
@ -536,7 +596,13 @@
:aria-lavel="$i18n.get('label_button_untrash')"
@click.prevent.stop="untrashOneItem(item.id)"
v-if="isOnTrash">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_recover_from_trash'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-undo"/>
</span>
</a>
@ -545,7 +611,13 @@
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<span class="icon">
<span
v-tooltip="{
content: isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('delete'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
@ -749,7 +821,13 @@
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
@ -757,7 +835,13 @@
:aria-lavel="$i18n.get('label_button_untrash')"
@click.prevent.stop="untrashOneItem(item.id)"
v-if="isOnTrash">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_recover_from_trash'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-undo"/>
</span>
</a>
@ -766,7 +850,13 @@
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<span class="icon">
<span
v-tooltip="{
content: isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('delete'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>

View File

@ -62,10 +62,23 @@
<div class="handle">
<span
v-if="!(isRepositoryLevel || metadatum.id == undefined || openedMetadatumId != '' || isUpdatingMetadataOrder)"
v-tooltip="{
content: $i18n.get('instruction_drag_and_drop_metadatum_sort'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon grip-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-drag"/>
</span>
<span class="icon icon-level-identifier">
<span
v-tooltip="{
content: (metadatum.collection_id == 'default') || isRepositoryLevel ? $i18n.get('label_repository_filter') : $i18n.get('label_collection_filter'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon icon-level-identifier">
<i
:class="{
'tainacan-icon-collections': (metadatum.collection_id != 'default' && !isRepositoryLevel),
@ -122,7 +135,14 @@
? 'hidden' : 'visible'
}"
@click.prevent="editMetadatum(metadatum)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
@ -134,7 +154,14 @@
? 'hidden' : 'visible'
}"
@click.prevent="removeMetadatum(metadatum)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-delete"/>
</span>
</a>
@ -173,7 +200,14 @@
:class="{ 'hightlighted-metadatum' : hightlightedMetadatum == metadatum.name, 'inherited-metadatum': isRepositoryLevel }"
v-for="(metadatum, index) in availableMetadatumList"
:key="index">
<span class="icon grip-icon">
<span
v-tooltip="{
content: $i18n.get('instruction_click_or_drag_metadatum_create'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon grip-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-drag"/>
</span>
<span class="metadatum-name">
@ -287,7 +321,14 @@
? 'visible' : 'hidden'
}"
@click.prevent="editMetadatumCustomMapper(props.row)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
@ -297,7 +338,14 @@
? 'visible' : 'hidden'
}"
@click.prevent="removeMetadatumCustomMapper(props.row)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-delete"/>
</span>
</a>

View File

@ -76,7 +76,7 @@
hide: 300,
},
content: bgProcess.name ? bgProcess.name : $i18n.get('label_unamed_process'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}">
{{ bgProcess.name ? bgProcess.name : $i18n.get('label_unamed_process') }}</p>
@ -93,7 +93,7 @@
hide: 300,
},
content: bgProcess.progress_label ? bgProcess.progress_label : $i18n.get('label_no_details_of_process'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}">
<span :class="{'occluding-content': bgProcess.progress_value }"><span class="has-text-weight-bold">{{ $i18n.get('label_progress') + " " }}</span>{{ bgProcess.progress_label ? bgProcess.progress_label : $i18n.get('label_no_details_of_process') }}</span>
@ -112,7 +112,7 @@
hide: 300,
},
content: getDate(bgProcess.queued_on),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}">
<span class="has-text-weight-bold">{{ $i18n.get('label_queued_on') + " " }}</span>{{ getDate(bgProcess.queued_on) }}</p>
@ -135,7 +135,7 @@
hide: 300,
},
content: $i18n.get('label_stop_process'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-if=" bgProcess.status === 'running' "
@ -150,7 +150,7 @@
hide: 300,
},
content: $i18n.get('label_process_completed'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-if=" ( bgProcess.status === 'finished' && !bgProcess.error_log ) || bgProcess.status === null"
@ -164,7 +164,7 @@
hide: 300,
},
content: $i18n.get('label_process_completed_with_errors'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-if=" bgProcess.status === 'finished-errors' || ( bgProcess.done > 0 && bgProcess.error_log && bgProcess.status === 'finished' ) "
@ -181,7 +181,7 @@
hide: 300,
},
content: $i18n.get('label_process_cancelled'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-if=" bgProcess.status === 'cancelled' "
@ -195,7 +195,7 @@
hide: 300,
},
content: $i18n.get('label_process_paused'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-if=" bgProcess.status === 'paused' "
@ -209,7 +209,7 @@
hide: 300,
},
content: $i18n.get('label_process_waiting'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-if=" bgProcess.status === 'waiting' "
@ -223,7 +223,7 @@
hide: 300,
},
content: $i18n.get('label_process_failed'),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-if="bgProcess.status === 'errored'"
@ -286,7 +286,7 @@
hide: 300,
},
content: getDate(bgProcess.processed_last),
autoHide: false,
autoHide: false, classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}">
<span class="has-text-weight-bold">{{ $i18n.get('label_last_processed_on') + " " }}</span>{{ getDate(bgProcess.processed_last) }}</p>

View File

@ -1,6 +1,7 @@
<template>
<div
style="width: 100%;">
<div
class="term-item"
:style="{
@ -14,7 +15,14 @@
class="icon children-icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-nextlevel"/>
</span>
<span class="children-dropdown icon">
<span
v-tooltip="{
content: $i18n.get('label_show_children_terms'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="children-dropdown icon">
<i
:class="{
'tainacan-icon-arrowright': !showChildren,
@ -45,18 +53,39 @@
class="controls"
:class="{'is-disabled': isEditingTerm}">
<a @click="addNewChildTerm(term, index)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_new_child'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-add"/>
</span>
</a>
<a
@click.prevent="editTerm()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
<a @click.prevent="tryToRemoveTerm()">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-delete"/>
</span>
</a>

View File

@ -147,7 +147,14 @@
id="button-edit"
:aria-label="$i18n.getFrom('taxonomies','edit_item')"
@click="onClickTaxonomy($event, taxonomy.id, index)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-edit"/>
</span>
</a>
@ -155,7 +162,14 @@
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneTaxonomy(taxonomy.id)">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>

View File

@ -15,7 +15,14 @@
:disabled="localTerms.length <= 0 || isLoadingTerms || isEditingTerm || order == 'asc'"
class="button is-white is-small"
@click="onChangeOrder('asc')">
<span class="icon gray-icon">
<span
v-tooltip="{
content: $i18n.get('label_sort_ascending'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-sortascending"/>
</span>
</button>
@ -23,7 +30,14 @@
:disabled="localTerms.length <= 0 || isLoadingTerms || isEditingTerm || order == 'desc'"
class="button is-white is-small"
@click="onChangeOrder('desc')">
<span class="icon gray-icon">
<span
v-tooltip="{
content: $i18n.get('label_sort_descending'),
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'bottom'
}"
class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-sortdescending"/>
</span>
</button>

View File

@ -14,7 +14,15 @@
tag="a"
to="/collections"
:class="activeRoute == 'CollectionsPage' || $route.params.collectionId != undefined ? 'is-active':''">
<span class="icon">
<span
v-tooltip="{
offset: 4,
content: isMenuCompressed ? $i18n.getFrom('collections', 'name') : '',
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-collections"/>
</span>
<span class="menu-text">{{ $i18n.getFrom('collections', 'name') }}</span>
@ -25,7 +33,15 @@
tag="a"
to="/items"
:class="activeRoute == 'ItemsPage' ? 'is-active':''">
<span class="icon">
<span
v-tooltip="{
offset: 4,
content: isMenuCompressed ? $i18n.getFrom('items', 'name') : '',
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-items"/>
</span>
<span class="menu-text">{{ $i18n.getFrom('items', 'name') }}</span>
@ -37,7 +53,15 @@
tag="a"
to="/metadata"
:class="activeRoute == 'MetadataPage' ? 'is-active':''">
<span class="icon">
<span
v-tooltip="{
offset: 4,
content: isMenuCompressed ? $i18n.get('metadata') : '',
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-metadata"/>
</span>
<span class="menu-text">{{ $i18n.get('metadata') }}</span>
@ -48,7 +72,15 @@
tag="a"
to="/filters"
:class="activeRoute == 'FiltersPage' ? 'is-active':''">
<span class="icon">
<span
v-tooltip="{
offset: 4,
content: isMenuCompressed ? $i18n.getFrom('filters', 'name') : '',
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-filters"/>
</span>
<span class="menu-text">{{ $i18n.getFrom('filters', 'name') }}</span>
@ -59,7 +91,15 @@
tag="a"
to="/taxonomies"
:class="activeRoute == 'Page' ? 'is-active':''">
<span class="icon">
<span
v-tooltip="{
offset: 4,
content: isMenuCompressed ? $i18n.getFrom('taxonomies', 'name') : '',
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-taxonomies"/>
</span>
<span class="menu-text">{{ $i18n.getFrom('taxonomies', 'name') }}</span>
@ -70,7 +110,15 @@
tag="a"
to="/activities"
:class="activeRoute == 'ActivitiesPage' ? 'is-active':''">
<span class="icon">
<span
v-tooltip="{
offset: 4,
content: isMenuCompressed ? $i18n.get('activities') : '',
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-activities"/>
</span>
<span class="menu-text">{{ $i18n.get('activities') }}</span>
@ -85,7 +133,15 @@
activeRoute == 'ImporterEditionForm' ||
activeRoute == 'ImporterCreationForm' ||
activeRoute == 'ImporterMappingForm' ) ? 'is-active':''">
<span class="icon">
<span
v-tooltip="{
offset: 4,
content: isMenuCompressed ? $i18n.get('importers') : '',
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-importers"/>
</span>
<span class="menu-text menu-text-import">{{ $i18n.get('importers') }}</span>
@ -98,7 +154,15 @@
:class="(
activeRoute == 'ExportersPage' ||
activeRoute == 'ExporterEditionForm') ? 'is-active':''">
<span class="icon">
<span
v-tooltip="{
offset: 4,
content: isMenuCompressed ? $i18n.get('exporters') : '',
autoHide: true,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-export"/>
</span>
<span class="menu-text">{{ $i18n.get('exporters') }}</span>

View File

@ -54,94 +54,122 @@
<ul class="menu-list level-right">
<li
:class="activeRoute == 'ItemPage' || activeRoute == 'CollectionItemsPage' || activeRoute == 'ItemEditionForm' || activeRoute == 'ItemCreatePage' ? 'is-active':''"
class="level-item">
<b-tooltip
:label="$i18n.get('items')"
position="is-bottom">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionItemsPath(id, '') }"
:aria-label="$i18n.get('label_collection_items')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-items"/>
</span>
<!-- <span class="menu-text">{{ $i18n.get('items') }}</span> -->
</router-link>
</b-tooltip>
class="level-item"
v-tooltip="{
delay: {
show: 300,
hide: 100,
},
content: $i18n.get('items'),
autoHide: false,
placement: 'bottom-start',
classes: ['header-tooltips']
}">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionItemsPath(id, '') }"
:aria-label="$i18n.get('label_collection_items')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-items"/>
</span>
<!-- <span class="menu-text">{{ $i18n.get('items') }}</span> -->
</router-link>
</li>
<li
v-if="currentUserCanEdit"
:class="activeRoute == 'CollectionEditionForm' ? 'is-active':''"
class="level-item">
<b-tooltip
:label="$i18n.get('label_settings')"
position="is-bottom">
<router-link
class="level-item"
v-tooltip="{
delay: {
show: 300,
hide: 100,
},
content: $i18n.get('label_settings'),
autoHide: false,
placement: 'bottom-start',
classes: ['header-tooltips']
}">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionEditPath(id) }"
:aria-label="$i18n.get('label_settings')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-settings"/>
</span>
<!-- <span class="menu-text">{{ $i18n.get('label_settings') }}</span> -->
</router-link>
</b-tooltip>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-settings"/>
</span>
<!-- <span class="menu-text">{{ $i18n.get('label_settings') }}</span> -->
</router-link>
</li>
<li
v-if="currentUserCanEdit"
:class="activeRoute == 'MetadataList' ? 'is-active':''"
class="level-item">
<b-tooltip
:label="$i18n.getFrom('metadata', 'name')"
position="is-bottom">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionMetadataPath(id) }"
:aria-label="$i18n.get('label_collection_metadata')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-metadata"/>
</span>
<!-- <span class="menu-text">{{ $i18n.getFrom('metadata', 'name') }}</span> -->
</router-link>
</b-tooltip>
class="level-item"
v-tooltip="{
delay: {
show: 300,
hide: 100,
},
content: $i18n.getFrom('metadata', 'name'),
autoHide: false,
placement: 'bottom-start',
classes: ['header-tooltips']
}">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionMetadataPath(id) }"
:aria-label="$i18n.get('label_collection_metadata')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-metadata"/>
</span>
<!-- <span class="menu-text">{{ $i18n.getFrom('metadata', 'name') }}</span> -->
</router-link>
</li>
<li
v-if="currentUserCanEdit"
:class="activeRoute == 'FiltersList' ? 'is-active':''"
class="level-item">
<b-tooltip
animated
:label="$i18n.getFrom('filters', 'name')"
position="is-bottom">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionFiltersPath(id) }"
:aria-label="$i18n.get('label_collection_filters')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-filters"/>
</span>
<!-- <span class="menu-text">{{ $i18n.getFrom('filters', 'name') }}</span> -->
</router-link>
</b-tooltip>
class="level-item"
v-tooltip="{
delay: {
show: 300,
hide: 100,
},
content: $i18n.getFrom('filters', 'name'),
autoHide: false,
placement: 'bottom-start',
classes: ['header-tooltips']
}">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionFiltersPath(id) }"
:aria-label="$i18n.get('label_collection_filters')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-filters"/>
</span>
<!-- <span class="menu-text">{{ $i18n.getFrom('filters', 'name') }}</span> -->
</router-link>
</li>
<li
:class="activeRoute == 'CollectionActivitiesPage' ? 'is-active':''"
class="level-item">
<b-tooltip
:label="$i18n.get('activities')"
position="is-bottom">
class="level-item"
v-tooltip="{
delay: {
show: 300,
hide: 100,
},
content: $i18n.get('activities'),
autoHide: false,
placement: 'bottom-start',
classes: ['header-tooltips']
}">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionActivitiesPath(id) }"
:aria-label="$i18n.get('label_collection_activities')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-activities"/>
</span>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-activities"/>
</span>
<!-- <span class="menu-text">{{ $i18n.get('activities') }}</span> -->
</router-link>
</b-tooltip>
</router-link>
</li>
</ul>
@ -222,6 +250,18 @@ export default {
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
.header-tooltips .tooltip-inner {
color: white;
text-shadow: 1px 1px $turquoise4;
background-color: $turquoise3;
font-size: 0.75rem;
font-weight: 400;
padding: 10px 14px;
}
.header-tooltips .tooltip-arrow {
border-color: $turquoise3;
}
// Tainacan Header
#tainacan-subheader {

View File

@ -7,7 +7,14 @@
<router-link
tag="a"
to="/">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_plugin_home_page'),
autoHide: true,
placement: 'auto',
classes: ['repository-header-tooltips']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-home has-text-blue5"/>
</span>
</router-link>
@ -85,7 +92,14 @@
<button
@click="showProcesses = !showProcesses"
class="button is-small is-white level-item">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('processes'),
autoHide: true,
placement: 'auto',
classes: ['repository-header-tooltips']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-processes"/>
</span>
</button>
@ -95,7 +109,14 @@
<a
class="level-item"
:href="wordpressAdmin">
<span class="icon">
<span
v-tooltip="{
content: $i18n.get('label_wordpress_admin_page'),
autoHide: true,
placement: 'auto',
classes: ['repository-header-tooltips']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-wordpress"/>
</span>
</a>
@ -163,6 +184,17 @@
@import "../../scss/_variables.scss";
.repository-header-tooltips .tooltip-inner {
color: white;
background-color: $blue3;
font-size: 0.75rem;
font-weight: 400;
padding: 10px 14px;
}
.repository-header-tooltips .tooltip-arrow {
border-color: $blue3;
}
// Tainacan Header
#tainacan-header {
background-color: white;

View File

@ -60,7 +60,7 @@
content: $i18n.get('label_view_repository'),
autoHide: false,
placement: 'bottom-end',
classes: ['header-tooltips']
classes: [ isRepositoryLevel ? 'repository-header-tooltips' : 'header-tooltips']
}">
<a
:href="repositoryURL"
@ -142,10 +142,26 @@ export default {
@import "../../scss/_variables.scss";
.header-tooltips .tooltip-inner {
color: $turquoise5;
color: white;
text-shadow: 1px 1px $turquoise4;
background-color: $turquoise3;
font-size: 0.75rem;
font-weight: 400;
padding: 0.75rem;
padding: 10px 14px;
}
.header-tooltips .tooltip-arrow {
border-color: $turquoise3;
}
.repository-header-tooltips .tooltip-inner {
color: white;
background-color: $blue3;
font-size: 0.75rem;
font-weight: 400;
padding: 10px 14px;
}
.repository-header-tooltips .tooltip-arrow {
border-color: $blue3;
}
// Tainacan Header

View File

@ -13,6 +13,7 @@
},
content: $i18n.get('label_filters_from') + ' ' + taxonomyFiltersCollectionNames[key] + ': ',
autoHide: false,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
v-if="taxonomyFilter.length > 0 && taxonomyFiltersCollectionNames != undefined && taxonomyFiltersCollectionNames[key] != undefined"
@ -56,6 +57,7 @@
},
content: $i18n.get('label_filters_from') + ' ' + taxonomyFiltersCollectionNames[key] + ': ',
autoHide: false,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
v-if="taxonomyFilter.length > 0 && taxonomyFiltersCollectionNames != undefined && taxonomyFiltersCollectionNames[key] != undefined"
@ -88,11 +90,100 @@
<hr v-if="taxonomyFilter.length > 0">
</div>
</template>
<template v-else>
<collections-filter
<template v-else-if="isRepositoryLevel && taxonomyFilters == undefined">
<collections-filter
:open="collapsed"
:query="getQuery"
v-if="isRepositoryLevel"/>
:query="getQuery"/>
<div
v-if="key == 'repository-filters'"
:key="index"
v-for="(repositoryCollectionFilter, key, index) of repositoryCollectionFilters">
<div
v-tooltip="{
delay: {
show: 500,
hide: 300,
},
content: $i18n.get('label_filters_from') + ' ' + repositoryCollectionNames[key] + ': ',
autoHide: false,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
v-if="repositoryCollectionFilter.length > 0 && repositoryCollectionNames != undefined && repositoryCollectionNames[key] != undefined"
class="collection-name">
{{ $i18n.get('label_filters_from') + " " + repositoryCollectionNames[key] + ": " }}
</div>
<div
v-if="repositoryCollectionFilter.length > 0 && !(repositoryCollectionNames != undefined && repositoryCollectionNames[key] != undefined)"
class="collection-name">
<span
style="width: 100%; height: 54px;"
class="icon has-text-centered loading-icon">
<div class="control has-icons-right is-loading is-clearfix" />
</span>
</div>
<tainacan-filter-item
v-show="!isMenuCompressed"
:query="getQuery"
v-for="(filter, filterIndex) in repositoryCollectionFilter"
:key="filterIndex"
:filter="filter"
:open="collapsed"
v-if="repositoryCollectionFilter.length > 0"
:is-repository-level="key == 'repository-filters'"/>
<!-- <p
class="has-text-gray is-size-7"
v-if="taxonomyFilter.length <= 0">
{{ $i18n.get('info_there_is_no_filter') }}
</p> -->
<hr v-if="repositoryCollectionFilters.length > 0">
</div>
<div
v-if="key != 'repository-filters'"
:key="index"
v-for="(repositoryCollectionFilter, key, index) of repositoryCollectionFilters">
<div
v-tooltip="{
delay: {
show: 500,
hide: 300,
},
content: $i18n.get('label_filters_from') + ' ' + repositoryCollectionNames[key] + ': ',
autoHide: false,
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : ''],
placement: 'auto-start'
}"
v-if="repositoryCollectionFilter.length > 0 && repositoryCollectionNames != undefined && repositoryCollectionNames[key] != undefined"
class="collection-name">
{{ $i18n.get('label_filters_from') + " " + repositoryCollectionNames[key] + ": " }}
</div>
<div
v-if="repositoryCollectionFilter.length > 0 && !(repositoryCollectionNames != undefined && repositoryCollectionNames[key] != undefined)"
class="collection-name">
<span
style="width: 100%; height: 54px;"
class="icon has-text-centered loading-icon">
<div class="control has-icons-right is-loading is-clearfix" />
</span>
</div>
<tainacan-filter-item
v-show="!isMenuCompressed"
:query="getQuery"
v-for="(filter, filterIndex) in repositoryCollectionFilter"
:key="filterIndex"
:filter="filter"
:open="collapsed"
v-if="repositoryCollectionFilter.length > 0"
:is-repository-level="key == 'repository-filters'"/>
<!-- <p
class="has-text-gray is-size-7"
v-if="taxonomyFilter.length <= 0">
{{ $i18n.get('info_there_is_no_filter') }}
</p> -->
<hr v-if="repositoryCollectionFilters.length > 0">
</div>
</template>
<template v-else>
<tainacan-filter-item
v-show="!isMenuCompressed"
:query="getQuery"
@ -112,7 +203,8 @@
export default {
data() {
return {
taxonomyFiltersCollectionNames: Object
taxonomyFiltersCollectionNames: {},
repositoryCollectionNames: {}
}
},
props: {
@ -120,7 +212,8 @@
collapsed: Boolean,
isRepositoryLevel: Boolean,
taxonomyFilters: Object,
taxonomy: String
taxonomy: String,
repositoryCollectionFilters: Object
},
watch: {
taxonomyFilters() {
@ -130,7 +223,24 @@
if (taxonomyFilter != 'repository-filters') {
this.fetchCollectionName(taxonomyFilter)
.then((collectionName) => {
this.$set(this.taxonomyFiltersCollectionNames, taxonomyFilter, collectionName);
this.$nextTick(() => {
this.$set(this.taxonomyFiltersCollectionNames, taxonomyFilter, collectionName);
});
});
}
}
}
},
repositoryCollectionFilters() {
if (this.repositoryCollectionFilters != undefined) {
this.$set(this.repositoryCollectionNames, 'repository-filters', this.$i18n.get('repository'));
for (let repositoryCollectionFilter of Object.keys(this.repositoryCollectionFilters)) {
if (repositoryCollectionFilter != 'repository-filters') {
this.fetchCollectionName(repositoryCollectionFilter)
.then((collectionName) => {
this.$nextTick(() => {
this.$set(this.repositoryCollectionNames, '' + repositoryCollectionFilter, collectionName);
});
});
}
}
@ -169,6 +279,7 @@
font-size: 0.875rem;
font-weight: 500;
margin-bottom: 0.875rem;
margin-top: 1rem;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;

View File

@ -38,10 +38,26 @@
aria-controls="items-list-results"
aria-labelledby="items-per-page-select"
@input="onChangeItemsPerPage">
<option value="12">12 &nbsp;</option>
<option value="24">24 &nbsp;</option>
<option value="48">48 &nbsp;</option>
<option value="96">96 &nbsp;</option>
<option
v-if="maxItemsPerPage >= 12"
value="12">
12 &nbsp;
</option>
<option
v-if="maxItemsPerPage >= 24"
value="24">
24 &nbsp;
</option>
<option
v-if="maxItemsPerPage >= 48"
value="48">
48 &nbsp;
</option>
<option
v-if="maxItemsPerPage >= 96"
value="96">
96 &nbsp;
</option>
</b-select>
</b-field>
</div>
@ -84,7 +100,11 @@
:current.sync="page"
order="is-centered"
size="is-small"
:per-page="itemsPerPage"/>
:per-page="itemsPerPage"
:aria-next-label="$i18n.get('label_next_page')"
:aria-previous-label="$i18n.get('label_previous_page')"
:aria-page-label="$i18n.get('label_page')"
:aria-current-label="$i18n.get('label_current_page')" />
</div>
</div>
</template>
@ -94,6 +114,11 @@ import { mapGetters } from 'vuex';
export default {
name: 'Pagination',
data() {
return {
maxItemsPerPage: tainacan_plugin.api_max_items_per_page
}
},
computed: {
totalItems(){
return this.getTotalItems();
@ -125,10 +150,13 @@ export default {
'getPostQuery'
]),
onChangeItemsPerPage(value) {
if( this.itemsPerPage == value){
if ( this.itemsPerPage == value){
return false;
} else if (Number(value) > Number(this.maxItemsPerPage)) {
this.$eventBusSearch.setItemsPerPage(this.maxItemsPerPage);
} else {
this.$eventBusSearch.setItemsPerPage(value);
}
this.$eventBusSearch.setItemsPerPage(value);
},
onPageChange(page) {
if(page == 0)

View File

@ -138,7 +138,7 @@ UserPrefsPlugin.install = function (Vue, options = {}) {
'fetch_only': 'thumbnail,creation_date,author_name',
'fetch_only_meta': '',
'taxonomies_order': 'desc',
'taxonomies_order_by': 'date',
'taxonomies_order_by': 'name',
'collections_order': 'desc',
'collections_order_by': 'date'
},

View File

@ -93,7 +93,11 @@
:current.sync="activitiesPage"
order="is-centered"
size="is-small"
:per-page="activitiesPerPage"/>
:per-page="activitiesPerPage"
:aria-next-label="$i18n.get('label_next_page')"
:aria-previous-label="$i18n.get('label_previous_page')"
:aria-page-label="$i18n.get('label_page')"
:aria-current-label="$i18n.get('label_current_page')"/>
</div>
</div>
<div
@ -130,7 +134,11 @@
:current.sync="processesPage"
order="is-centered"
size="is-small"
:per-page="processesPerPage"/>
:per-page="processesPerPage"
:aria-next-label="$i18n.get('label_next_page')"
:aria-previous-label="$i18n.get('label_previous_page')"
:aria-page-label="$i18n.get('label_page')"
:aria-current-label="$i18n.get('label_current_page')"/>
</div>
</div>
</div>

View File

@ -71,19 +71,35 @@
</option>
</b-select>
<button
:disabled="collections.length <= 0 || isLoading || order == 'asc'"
:disabled="collections.length <= 0 || isLoading || order == 'desc'"
class="button is-white is-small"
@click="onChangeOrder('asc')">
<span class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortascending tainacan-icon-20px"/>
@click="onChangeOrder('desc')"
:aria-label="$i18n.get('label_sort_descending')">
<span
v-tooltip="{
content: $i18n.get('label_sort_descending'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', 'repository-tooltip']
}"
class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortdescending tainacan-icon-20px"/>
</span>
</button>
<button
:disabled="collections.length <= 0 || isLoading || order == 'desc'"
:disabled="collections.length <= 0 || isLoading || order == 'asc'"
class="button is-white is-small"
@click="onChangeOrder('desc')">
<span class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortdescending tainacan-icon-20px"/>
@click="onChangeOrder('asc')"
:aria-label="$i18n.get('label_sort_ascending')">
<span
v-tooltip="{
content: $i18n.get('label_sort_ascending'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', 'repository-tooltip']
}"
class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortascending tainacan-icon-20px"/>
</span>
</button>
</b-field>
@ -218,7 +234,11 @@
:current.sync="page"
order="is-centered"
size="is-small"
:per-page="collectionsPerPage"/>
:per-page="collectionsPerPage"
:aria-next-label="$i18n.get('label_next_page')"
:aria-previous-label="$i18n.get('label_previous_page')"
:aria-page-label="$i18n.get('label_page')"
:aria-current-label="$i18n.get('label_current_page')"/>
</div>
</div>
</div>

View File

@ -18,7 +18,8 @@
},
content: isFiltersMenuCompressed ? $i18n.get('label_show_filters') : $i18n.get('label_hide_filters'),
autoHide: false,
placement: 'auto-start'
placement: 'auto-start',
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : '']
}"
v-if="!openAdvancedSearch && !(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen)"
class="is-hidden-mobile"
@ -81,9 +82,7 @@
<span
@click="updateSearch()"
class="icon is-right">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-search"/>
</span>
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-search"/>
</span>
</div>
</div>
@ -121,6 +120,7 @@
v-if="!isLoadingFilters &&
((filters.length >= 0 && isRepositoryLevel) || filters.length > 0)"
:filters="filters"
:repository-collection-filters="repositoryCollectionFilters"
:collapsed="collapseAll"
:is-repository-level="isRepositoryLevel"/>
@ -238,7 +238,8 @@
},
content: (totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry') ? (adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry') ? $i18n.get('info_current_view_mode_metadata_not_allowed') : $i18n.get('info_cant_select_metadata_without_items') : '',
autoHide: false,
placement: 'auto-start'
placement: 'auto-start',
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : '']
}"
ref="displayedMetadataDropdown"
:mobile-modal="true"
@ -333,7 +334,14 @@
:aria-label="$i18n.get('label_sort_descending')"
:disabled="totalItems <= 0 || order == 'DESC'"
@click="onChangeOrder()">
<span class="icon is-small gray-icon">
<span
v-tooltip="{
content: $i18n.get('label_sort_descending'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : '']
}"
class="icon is-small gray-icon">
<i class="tainacan-icon tainacan-icon-sortdescending"/>
</span>
</button>
@ -343,7 +351,14 @@
:aria-label="$i18n.get('label_sort_ascending')"
class="button is-white is-small"
@click="onChangeOrder()">
<span class="icon is-small gray-icon">
<span
v-tooltip="{
content: $i18n.get('label_sort_ascending'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : '']
}"
class="icon is-small gray-icon">
<i class="tainacan-icon tainacan-icon-sortascending"/>
</span>
</button>
@ -693,7 +708,7 @@
:collection-id="collectionId"
:displayed-metadata="displayedMetadata"
:items="items"
:is-filters-menu-compressed="isFiltersMenuCompressed"
:is-filters-menu-compressed="isFiltersMenuCompressed || openAdvancedSearch "
:total-items="totalItems"
:is-loading="isLoadingItems"
:is="registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].component : ''"/>
@ -772,6 +787,7 @@
((filters.length >= 0 && isRepositoryLevel) || filters.length > 0)"
:filters="filters"
:collapsed="collapseAll"
:repository-collection-filters="repositoryCollectionFilters"
:is-repository-level="isRepositoryLevel"/>
<section
@ -882,6 +898,9 @@
filters() {
return this.getFilters();
},
repositoryCollectionFilters() {
return this.getRepositoryCollectionFilters();
},
metadata() {
return this.getMetadata();
},
@ -964,10 +983,12 @@
'getMetadata'
]),
...mapActions('filter', [
'fetchFilters'
'fetchFilters',
'fetchRepositoryCollectionFilters'
]),
...mapGetters('filter', [
'getFilters'
'getFilters',
'getRepositoryCollectionFilters'
]),
...mapGetters('search', [
'getSearchQuery',
@ -1111,6 +1132,13 @@
})
.then(() => this.isLoadingFilters = false)
.catch(() => this.isLoadingFilters = false);
// On repository level we also fetch collection filters
if (this.isRepositoryLevel) {
this.fetchRepositoryCollectionFilters()
.catch(() => this.isLoadingFilters = false);
}
},
prepareMetadata() {

View File

@ -34,22 +34,36 @@
{{ option.label }}
</option>
</b-select>
<button
:disabled="taxonomies.length <= 0 || isLoading || order == 'asc'"
class="button is-white is-small"
@click="onChangeOrder('asc')">
<span class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortascending tainacan-icon-20px"/>
</span>
</button>
<button
:disabled="taxonomies.length <= 0 || isLoading || order == 'desc'"
class="button is-white is-small"
@click="onChangeOrder('desc')">
<span class="icon gray-icon is-small">
<span
v-tooltip="{
content: $i18n.get('label_sort_descending'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', 'repository-tooltip']
}"
class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortdescending tainacan-icon-20px"/>
</span>
</button>
<button
:disabled="taxonomies.length <= 0 || isLoading || order == 'asc'"
class="button is-white is-small"
@click="onChangeOrder('asc')">
<span
v-tooltip="{
content: $i18n.get('label_sort_ascending'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', 'repository-tooltip']
}"
class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortascending tainacan-icon-20px"/>
</span>
</button>
</b-field>
</div>
@ -142,7 +156,12 @@
:current.sync="page"
order="is-centered"
size="is-small"
:per-page="taxonomiesPerPage"/>
:per-page="taxonomiesPerPage"
:aria-next-label="$i18n.get('label_next_page')"
:aria-previous-label="$i18n.get('label_previous_page')"
:aria-page-label="$i18n.get('label_page')"
:aria-current-label="$i18n.get('label_current_page')"/>
</div>
</div>
</div>
@ -286,8 +305,8 @@
if (this.orderBy != this.$userPrefs.get('taxonomies_order_by'))
this.orderBy = this.$userPrefs.get('taxonomies_order_by');
if (!this.orderBy) {
this.orderBy = 'date';
this.$userPrefs.set('taxonomies_order_by', 'date');
this.orderBy = 'name';
this.$userPrefs.set('taxonomies_order_by', 'name');
}
this.load();

View File

@ -19,7 +19,8 @@
},
content: isFiltersMenuCompressed ? $i18n.get('label_show_filters') : $i18n.get('label_hide_filters'),
autoHide: false,
placement: 'auto-start'
placement: 'auto-start',
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : '']
}"
v-if="!openAdvancedSearch && !(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen)"
class="is-hidden-mobile"
@ -79,9 +80,7 @@
<span
@click="updateSearch()"
class="icon is-right">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-search"/>
</span>
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-search"/>
</span>
</div>
</div>
@ -124,7 +123,6 @@
:taxonomy="taxonomy"
:collapsed="collapseAll"
:is-repository-level="isRepositoryLevel"/>
<section
v-else
class="is-grouped-centered section">
@ -224,7 +222,8 @@
},
content: (totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry') ? (adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry') ? $i18n.get('info_current_view_mode_metadata_not_allowed') : $i18n.get('info_cant_select_metadata_without_items') : '',
autoHide: false,
placement: 'auto-start'
placement: 'auto-start',
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : '']
}"
ref="displayedMetadataDropdown"
:mobile-modal="true"
@ -319,7 +318,14 @@
:aria-label="$i18n.get('label_sort_descending')"
:disabled="totalItems <= 0 || order == 'DESC'"
@click="onChangeOrder()">
<span class="icon is-small gray-icon">
<span
v-tooltip="{
content: $i18n.get('label_sort_descending'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : '']
}"
class="icon is-small gray-icon">
<i class="tainacan-icon tainacan-icon-sortdescending"/>
</span>
</button>
@ -329,7 +335,14 @@
:aria-label="$i18n.get('label_sort_ascending')"
class="button is-white is-small"
@click="onChangeOrder()">
<span class="icon is-small gray-icon">
<span
v-tooltip="{
content: $i18n.get('label_sort_ascending'),
autoHide: true,
placement: 'bottom',
classes: ['tooltip', isRepositoryLevel ? 'repository-tooltip' : '']
}"
class="icon is-small gray-icon">
<i class="tainacan-icon tainacan-icon-sortascending"/>
</span>
</button>

View File

@ -3,6 +3,14 @@
.b-tooltip::after {
box-shadow: none;
}
.repository-tooltip {
.tooltip-inner {
background: $blue1 !important;
}
.tooltip-arrow {
border-color: $blue1 !important;
}
}
.tooltip {
z-index: 999999999;
display: block !important;
@ -16,7 +24,7 @@
color: $gray5;
font-size: 0.6875rem;
border-radius: 5px;
padding: 20px;
padding: 10px 14px;
max-width: 280px;
max-height: 200px;
overflow-x: auto;

View File

@ -65,6 +65,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'unified' => __( 'Unified', 'tainacan' ),
'add_another_search_criterion' => __( 'Add another search criterion', 'tainacan' ),
'add_one_search_criterion' => __( 'Add one search criterion', 'tainacan' ),
'remove_search_criterion' => __( 'Remove search criterion', 'tainacan' ),
'clear_search' => __( 'Clear search', 'tainacan' ),
'run' => __( 'Run', 'tainacan' ),
'edit_search' => __( 'Edit search', 'tainacan' ),
@ -78,6 +79,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'new_action' => __( 'New action', 'tainacan' ),
'clear_radio' => __( 'Clear selected radio', 'tainacan' ),
'undo' => __( 'Undo', 'tainacan' ),
'delete' => __( 'Delete', 'tainacan' ),
// Wordpress Status
'publish' => __( 'Publish', 'tainacan' ),
@ -384,6 +386,24 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_no_collections_using_taxonomy' => __( 'There is no collection using this taxonomy', 'tainacan' ),
'label_collections_using' => __( 'Collections using', 'tainacan' ),
'label_select_all_%s_items' => __( 'Select all %s items', 'tainacan' ),
'label_next_page' => __( 'Next page', 'tainacan' ),
'label_previous_page' => __( 'Previous page', 'tainacan' ),
'label_page' => __( 'Page', 'tainacan' ),
'label_current_page' => __( 'Current page', 'tainacan' ),
'label_shrink_menu' => __( 'Shrink menu', 'tainacan' ),
'label_document_uploaded' => __( 'Document uploaded', 'tainacan' ),
'label_repository_filter' => __( 'Repository filter', 'tainacan' ),
'label_repository_metadatum' => __( 'Repository metadatum', 'tainacan' ),
'label_collection_filter' => __( 'Collection filter', 'tainacan' ),
'label_collection_metadatum' => __( 'Collection metadatum', 'tainacan' ),
'label_recover_from_trash' => __( 'Recover from trash', 'tainacan' ),
'label_show_children_terms' => __( 'Show children terms', 'tainacan' ),
'label_begin_slide_transition' => __( 'Begin slide transition', 'tainacan' ),
'label_pause_slide_transition' => __( 'Pause slide transition', 'tainacan' ),
'label_next_group_slides' => __( 'Next group of slides', 'tainacan' ),
'label_previous_group_slides' => __( 'Previous group of slides', 'tainacan' ),
'label_plugin_home_page' => __( 'Plugin home page', 'tainacan' ),
'label_wordpress_admin_page' => __( 'WordPress Admin Page', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -424,6 +444,10 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_select_a_collection' => __( 'Select a collection', 'tainacan' ),
'instruction_hover_a_filter_type_to_preview' => __( 'Hover a filter type to preview', 'tainacan' ),
'instruction_never_show_message_again' => __( 'Never show me this message again', 'tainacan' ),
'instruction_click_or_drag_filter_create' => __( 'Click or drag and drop to create a new filter', 'tainacan' ),
'instruction_click_or_drag_metadatum_create' => __( 'Click or drag and drop to create a new metadatum', 'tainacan' ),
'instruction_drag_and_drop_filter_sort' => __( 'Drag and drop to change filter order', 'tainacan' ),
'instruction_drag_and_drop_metadatum_sort' => __( 'Drag and drop to change metadatum order', 'tainacan' ),
// Info. Other feedback to user.
'info_error_invalid_date' => __( 'Invalid date', 'tainacan' ),

View File

@ -101,16 +101,40 @@ class REST_Taxonomies_Controller extends REST_Controller {
if ( $request['context'] === 'edit' ) {
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
$item_arr['collections'] = [];
if ( is_array($tax_collections = $item->get_collections()) ) {
foreach ($tax_collections as $tax_collection) {
if ( $tax_collection instanceof \Tainacan\Entities\Collection ) {
$item_arr['collections'][] = $tax_collection->_toArray();
}
}
}
// $item_arr['collections'] = [];
// if ( is_array($tax_collections = $item->get_collections()) ) {
// foreach ($tax_collections as $tax_collection) {
// if ( $tax_collection instanceof \Tainacan\Entities\Collection ) {
// $item_arr['collections'][] = $tax_collection->_toArray();
// }
// }
//
// }
}
/**
*
*
* See issue #229
*
*/
$item_arr['collections'] = [];
$item_arr['collections_ids'] = [];
$taxonomy = get_taxonomy( $item->get_db_identifier() );
foreach ($taxonomy->object_type as $slug) {
$tax_collection = Repositories\Collections::get_instance()->fetch_by_db_identifier($slug);
if ( $tax_collection instanceof \Tainacan\Entities\Collection ) {
$item_arr['collections'][] = $tax_collection->_toArray();
$item_arr['collections_ids'][] = $tax_collection->get_id();
}
}
} else {
$attributes_to_filter = $request['fetch_only'];
@ -284,9 +308,12 @@ class REST_Taxonomies_Controller extends REST_Controller {
* @return bool|\WP_Error
*/
public function get_items_permissions_check( $request ) {
if('edit' === $request['context'] && !$this->taxonomy_repository->can_read($this->taxonomy)) {
if('edit' === $request['context'] && !is_user_logged_in()) {
return false;
}
// if(!$this->taxonomy_repository->can_read($this->taxonomy)) {
// return false;
// }
return true;
}

View File

@ -2,8 +2,8 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20161003 at Thu Feb 7 11:51:11 2019
By www-data
Created by FontForge 20170910 at Thu Apr 11 17:41:05 2019
By Jimmy Wärting
</metadata>
<defs>
<font id="TainacanIcons" horiz-adv-x="1000" >
@ -45,25 +45,25 @@ d="M583 254v-328q3 -21 -12 -35q-12 -12 -29 -12t-30 12l-83 84q-15 15 -12 35v244h-
<glyph glyph-name="importers" unicode="importers"
d="M417 84v124h-332v84h332v124l167 -166zM833 0q0 -34 -24 -58.5t-59 -24.5h-499q-35 0 -59 24.5t-24 58.5v125h83v-125h499v500h-499v-125h-83v125q0 34 24 58.5t59 24.5h499q35 0 59 -24t24 -59v-500z" />
<glyph glyph-name="settings" unicode="settings"
d="M817 163q12 -9 4 -22l-66 -115q-7 -12 -21 -7l-82 33q-14 -10 -27.5 -18t-29.5 -15l-12 -88q-2 -14 -16 -14h-134q-14 0 -16 14l-13 88q-27 12 -56 33l-83 -33q-13 -6 -20 7l-67 115q-7 13 4 22l71 55q-3 15 -3 32t3 32l-70 55q-12 9 -4 22l66 115q7 12 21 7l82 -33
q14 10 27.5 18t29.5 15l12 88q2 14 16 14h134q14 0 16 -14l13 -88q27 -12 56 -33l83 33q13 6 20 -7l67 -115q7 -13 -4 -22l-71 -55q3 -15 3 -32q0 -8 -0.5 -16t-1.5 -16zM500 125q26 0 48.5 10t39.5 27t27 39.5t10 48.5t-10 48.5t-27 39.5t-39.5 27t-48.5 10t-48.5 -10
t-39.5 -27t-27 -39.5t-10 -48.5t10 -48.5t27 -39.5t39.5 -27t48.5 -10z" />
d="M817 163q12 -9 4 -22l-66 -115q-7 -12 -21 -7l-82 33q-14 -10 -27.5 -18t-29.5 -15l-12 -88q-2 -14 -16 -14h-134q-14 0 -16 14l-13 88q-15 7 -28.5 15t-27.5 18l-83 -33q-5 -2 -11 0t-9 7l-67 115q-7 13 4 22l71 55q-3 15 -3 32t3 32l-70 55q-12 9 -4 22l66 115
q7 12 21 7l82 -33q14 10 27.5 18t29.5 15l12 88q2 14 16 14h134q14 0 16 -14l13 -88q15 -7 28.5 -15t27.5 -18l83 33q5 2 11 0t9 -7l67 -115q7 -13 -4 -22l-71 -55q3 -15 3 -32q0 -8 -0.5 -16t-1.5 -16zM500 125q26 0 48.5 10t39.5 27t27 39.5t10 48.5t-10 48.5t-27 39.5
t-39.5 27t-48.5 10t-48.5 -10t-39.5 -27t-27 -39.5t-10 -48.5t10 -48.5t27 -39.5t39.5 -27t48.5 -10z" />
<glyph glyph-name="uni21B8" unicode="home"
d="M208 -125v333h-125l417 375l417 -375h-125v-333h-209v250h-166v-250h-209z" />
<glyph glyph-name="tour" unicode="tour"
d="M792 668q35 0 59 -24.5t24 -59.5v-583q0 -35 -24 -59.5t-59 -24.5h-167l-125 -125l-125 125h-167q-35 0 -59 24.5t-24 59.5v583q0 35 24 59.5t59 24.5h584zM542 84h-84v-83h84v83zM628 324q18 18 28.5 42t10.5 52q0 35 -13 65t-36 52.5t-53 35.5t-65 13q-34 0 -64.5 -13
t-53.5 -35.5t-36 -52.5t-13 -65h84q0 34 24 58.5t59 24.5t59 -24.5t24 -58.5q0 -35 -24 -59l-52 -53q-23 -23 -36 -53t-13 -65v-20h84q0 47 12.5 70.5t35.5 46.5z" />
t-53.5 -35.5t-36 -52.5t-13 -65h84q0 34 24 58.5t59 24.5t59 -24.5t24 -58.5q0 -35 -24 -59l-52 -53q-23 -23 -36 -53t-13 -65v-20h84q0 23 3.5 40t9.5 30.5t15 24.5t20 22z" />
<glyph glyph-name="processes" unicode="processes"
d="M375 625l167 -167h-126v-291h-83v291h-125zM667 42h125l-167 -167l-167 167h126v291h83v-291z" />
d="M542 458h-126v-291h-83v291h-125l167 167zM792 42l-167 -167l-167 167h126v291h83v-291h125z" />
<glyph glyph-name="help" unicode="help"
d="M458 83h84v-83h-84v83zM500 666q86 0 162 -32.5t132.5 -89t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89t162 32.5zM500 -84q69 0 129.5 26.5t106 71.5t71.5 106t26 130
t-26 129.5t-71.5 105.5t-106 71.5t-129.5 26.5t-129.5 -26.5t-106 -71.5t-71.5 -105.5t-26 -129.5t26 -130t71.5 -106t106 -71.5t129.5 -26.5zM500 500q35 0 65 -13t53 -36t36 -53t13 -65q0 -39 -19.5 -63.5t-43 -45t-43 -42.5t-19.5 -57h-84q0 51 19.5 78t43 45.5t43 36
t19.5 48.5q0 35 -24 59t-59 24t-59 -24t-24 -59h-84q0 35 13 65t36 53t53.5 36t64.5 13z" />
t-26 129.5t-71.5 105.5t-106 71.5t-129.5 26.5t-129.5 -26.5t-106 -71.5t-71.5 -105.5t-26 -129.5t26 -130t71.5 -106t106 -71.5t129.5 -26.5zM500 500q35 0 65 -13t53 -36t36 -53t13 -65q0 -39 -19.5 -63.5t-43 -45t-43 -42.5t-19.5 -57h-84q0 34 9.5 56.5t23 39t30 28
t30 23.5t23 26t9.5 35q0 35 -24 59t-59 24t-59 -24t-24 -59h-84q0 35 13 65t36 53t53.5 36t64.5 13z" />
<glyph glyph-name="share" unicode="share"
d="M668 44q35 32 82 32q51 0 86.5 -35.5t35.5 -86.5t-35.5 -86t-86.5 -35t-86.5 35t-35.5 86q0 7 1 14t3 13l-297 174q-17 -16 -38.5 -25t-46.5 -9q-26 0 -48.5 10t-39.5 27t-27 39.5t-10 48.5t10 48.5t27 39.5t39.5 27t48.5 10q25 0 46.5 -9t38.5 -25l294 172q-2 7 -3 14
t-1 15q0 26 10 48.5t27 39.5t39.5 27t48.5 10t48.5 -10t39.5 -27t27 -39.5t10 -48.5t-10 -48.5t-27 -39.5t-39.5 -27t-48.5 -10q-25 0 -46.5 9t-38.5 24l-294 -171q2 -7 3 -14t1 -15t-1 -15t-3 -14z" />
d="M750 76q25 0 47.5 -9.5t39 -26t26 -39t9.5 -47.5t-9.5 -47t-26 -38.5t-39 -26t-47.5 -9.5t-47.5 9.5t-39 26t-26 38.5t-9.5 47q0 7 1 14t3 13l-297 174q-17 -16 -38.5 -25t-46.5 -9q-26 0 -48.5 10t-39.5 27t-27 39.5t-10 48.5t10 48.5t27 39.5t39.5 27t48.5 10
q25 0 46.5 -9t38.5 -25l294 172q-2 7 -3 14t-1 15q0 26 10 48.5t27 39.5t39.5 27t48.5 10t48.5 -10t39.5 -27t27 -39.5t10 -48.5t-10 -48.5t-27 -39.5t-39.5 -27t-48.5 -10q-25 0 -46.5 9t-38.5 24l-294 -171q2 -7 3 -14t1 -15t-1 -15t-3 -14l297 -173q35 32 82 32z" />
<glyph glyph-name="export" unicode="export"
d="M958 242l-166 166v-124h-292v-84h292v-124zM84 -9v501q0 35 24 59.5t59 24.5h460q35 0 59 -24.5t24 -59.5v-125h-83v125h-460v-501h460v126h83v-126q0 -35 -24 -59.5t-59 -24.5h-460q-35 0 -59 24.5t-24 59.5z" />
d="M958 242l-166 166v-124h-292v-84h292v-124zM84 -9v501q0 18 6.5 33t18 26.5t26.5 18t32 6.5h460q35 0 59 -24.5t24 -59.5v-125h-83v125h-460v-501h460v126h83v-126q0 -35 -24 -59.5t-59 -24.5h-460q-35 0 -59 24.5t-24 59.5z" />
<glyph glyph-name="url" unicode="url"
d="M162 251q0 -27 10 -50.5t28 -41t41.5 -27.5t50.5 -10h166v-79h-166q-43 0 -81.5 16.5t-66.5 44.5t-44.5 66t-16.5 81t16.5 81t44.5 66.5t66.5 45t81.5 16.5h166v-80h-166q-27 0 -50.5 -10t-41.5 -27.5t-28 -41t-10 -50.5zM333 293h334v-84h-334v84zM709 460
q43 0 81 -16.5t66 -45t44.5 -66.5t16.5 -81t-16.5 -81t-44.5 -66.5t-66 -45t-81 -16.5h-167v80h167q27 0 50.5 10t41 27.5t27.5 41t10 50.5t-10 50.5t-27.5 41t-41 27.5t-50.5 10h-167v80h167z" />
@ -73,7 +73,7 @@ t139 24t97 57.5t61 69t31 57.5q-9 22 -31 57.5t-61 69t-97 58t-139 24.5zM500 543q63
q28 82 83 146q24 27 55.5 53.5t72.5 47t92 33t114 12.5v0z" />
<glyph glyph-name="search" unicode="search"
d="M207 337q0 -42 16 -79.5t44 -65.5t65.5 -44t80.5 -16q42 0 79.5 16t65.5 44t44 65.5t16 79.5q0 43 -16 80.5t-44 65.5t-65.5 44t-79.5 16q-43 0 -80.5 -16t-65.5 -44t-44 -65.5t-16 -80.5zM125 337q0 60 22.5 112.5t61.5 91.5t91.5 61.5t112.5 22.5t112.5 -22.5
t91.5 -61.5t61.5 -91.5t22.5 -112.5q0 -38 -9 -72t-26 -65l209 -209q-3 -31 -17 -56q-11 -21 -34 -39.5t-65 -20.5l-209 209q-31 -17 -65 -26t-72 -9q-60 0 -112.5 22.5t-91.5 61.5t-61.5 91.5t-22.5 112.5z" />
t91.5 -61.5t61.5 -91.5t22.5 -112.5q0 -38 -9 -72t-26 -65l209 -209q-3 -31 -17 -56q-11 -21 -34.5 -39.5t-64.5 -20.5l-209 209q-31 -17 -65 -26t-72 -9q-60 0 -112.5 22.5t-91.5 61.5t-61.5 91.5t-22.5 112.5z" />
<glyph glyph-name="edit" unicode="edit"
d="M595 519l174 -174l-512 -512h-174v174zM819 395l-174 174l85 84q14 14 32.5 14t32.5 -14l108 -108q14 -14 14 -32.5t-14 -32.5z" />
<glyph glyph-name="uni2421" unicode="delete"
@ -81,7 +81,7 @@ d="M250 458h500v-500q0 -35 -24 -59t-59 -24h-334q-34 0 -58.5 24t-24.5 59v500zM792
<glyph glyph-name="deleteforever" unicode="deleteforever"
d="M250 458h500v-500q0 -35 -24 -59t-59 -24h-334q-34 0 -58.5 24t-24.5 59v500zM458 167l-104 -105l42 -41l104 104l104 -104l42 42l-104 104l104 104l-42 42l-104 -105l-104 105l-42 -42zM792 583v-83h-584v83h146l42 42h208l42 -42h146z" />
<glyph glyph-name="undo" unicode="undo"
d="M125 250l292 292v-167q109 -16 188.5 -60t134 -106.5t87 -138t48.5 -153.5q-78 110 -189.5 161t-268.5 51v-171z" />
d="M417 542v-167q109 -16 188.5 -60t134 -106.5t87 -138t48.5 -153.5q-78 110 -189.5 161t-268.5 51v-171l-292 292z" />
<glyph glyph-name="add" unicode="add"
d="M500 666q86 0 162 -33t132.5 -89.5t89.5 -132t33 -161.5t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89 132.5t-32.5 162t32.5 161.5t89 132t132.5 89.5t162 33zM750 312h-188v187h-124v-187h-188v-125h188v-187h124v187h188v125z" />
<glyph glyph-name="public" unicode="public"
@ -90,14 +90,14 @@ q-4 -18 -6.5 -36.5t-2.5 -38.5q0 -64 22.5 -120.5t62 -101t93 -73t114.5 -36.5v81zM5
" />
<glyph glyph-name="private" unicode="private"
d="M750 416q35 0 59 -24t24 -59v-417q0 -35 -24 -59t-59 -24h-500q-35 0 -59 24.5t-24 58.5v417q0 35 24 59t59 24h42v84q0 43 16.5 81t44.5 66t66 44.5t81 16.5t81 -16.5t66 -44.5t44.5 -66t16.5 -81v-84h42zM500 41q35 0 59 24.5t24 59.5t-24 59t-59 24t-59 -24t-24 -59
t24 -59.5t59 -24.5zM625 500q0 54 -35.5 89.5t-89.5 35.5t-89.5 -35.5t-35.5 -89.5v-84h250v84z" />
t24 -59.5t59 -24.5zM625 500q0 27 -9.5 49.5t-26.5 39.5t-39.5 26.5t-49.5 9.5t-49.5 -9.5t-39.5 -26.5t-26.5 -39.5t-9.5 -49.5v-84h250v84z" />
<glyph glyph-name="draft" unicode="draft"
d="M709 417h-417v-84h417v84zM709 250h-417v-83h417v83zM583 83h-291v-83h291v83zM500 584q-17 0 -29.5 -12.5t-12.5 -29.5t12.5 -29.5t29.5 -12.5t29.5 12.5t12.5 29.5t-12.5 29.5t-29.5 12.5zM792 584q35 0 59 -24.5t24 -59.5v-584q0 -35 -24 -59t-59 -24h-584
q-35 0 -59 24t-24 59v584q0 35 24 59.5t59 24.5h174q14 36 45.5 59.5t72.5 23.5t72.5 -23.5t45.5 -59.5h174z" />
<glyph glyph-name="download" unicode="download"
d="M375 376v250h250v-250h167l-292 -292l-292 292h167zM208 1h584v-84h-584v84z" />
d="M208 1h584v-84h-584v84zM500 84l-292 292h167v250h250v-250h167z" />
<glyph glyph-name="upload" unicode="upload"
d="M208 125l292 292l292 -292h-167v-250h-250v250h-167zM208 500v84h584v-84h-584z" />
d="M792 500h-584v84h584v-84zM500 417l292 -292h-167v-250h-250v250h-167z" />
<glyph glyph-name="playfill" unicode="playfill"
d="M500 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89.5t162 33zM667 250l-250 188v-376z" />
<glyph glyph-name="play" unicode="play"
@ -121,7 +121,7 @@ t129.5 26q49 0 94 -13.5t83 -38.5l-60 -60q-26 14 -55.5 21.5t-61.5 7.5q-52 0 -97.5
<glyph glyph-name="approvedcircle" unicode="approvedcircle"
d="M501 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89.5t162 33zM793 417l-59 59l-316 -316l-150 149l-59 -59l209 -208z" />
<glyph glyph-name="approved" unicode="approved"
d="M145 191l59 59l173 -174l440 440l58 -59l-498 -498z" />
d="M817 516l58 -59l-498 -498l-232 232l59 59l173 -174z" />
<glyph glyph-name="alertcircle" unicode="alertcircle"
d="M500 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89.5t162 33zM542 125h-84v-83h84v83zM542 459h-84v-251h84v251z" />
<glyph glyph-name="alert" unicode="alert"
@ -130,15 +130,15 @@ d="M542 0h-84v84h84v-84zM542 500v-334h-84v334h84z" />
d="M500 667q87 0 163 -32.5t132.5 -89t89 -132.5t32.5 -163t-32.5 -163t-89 -132.5t-132.5 -89t-163 -32.5t-163 32.5t-132.5 89t-89 132.5t-32.5 163t32.5 163t89 132.5t132.5 89t163 32.5zM559 250l150 150l-59 59l-150 -150l-150 150l-59 -59l150 -150l-150 -150l59 -59
l150 150l150 -150l59 59z" />
<glyph glyph-name="repproved" unicode="repproved"
d="M441 251l-233 233l59 59l233 -233l233 233l59 -59l-233 -233l233 -233l-59 -59l-233 233l-233 -233l-59 59z" />
<glyph glyph-name="uni2190" unicode="arrowleft"
d="M584 460v-418l-209 209z" />
<glyph glyph-name="uni2192" unicode="arrowright"
d="M559 251l233 -233l-59 -59l-233 233l-233 -233l-59 59l233 233l-233 233l59 59l233 -233l233 233l59 -59z" />
<glyph glyph-name="arrowleft" unicode="arrowleft"
d="M584 42l-209 209l209 209v-418z" />
<glyph glyph-name="arrowright" unicode="arrowright"
d="M417 460l208 -209l-208 -209v418z" />
<glyph glyph-name="uni2191" unicode="arrowup"
<glyph glyph-name="arrowup" unicode="arrowup"
d="M291 167l209 208l208 -208h-417z" />
<glyph glyph-name="uni2193" unicode="arrowdown"
d="M291 334h418l-209 -209z" />
<glyph glyph-name="arrowdown" unicode="arrowdown"
d="M709 334l-209 -209l-209 209h418z" />
<glyph glyph-name="next" unicode="next"
d="M379 -5l255 256l-255 256l78 78l334 -334l-334 -334z" />
<glyph glyph-name="previous" unicode="previous"
@ -148,10 +148,10 @@ d="M125 334h458v209l292 -292l-292 -292v209h-458v166z" />
<glyph glyph-name="video" unicode="video"
d="M875 479v-458l-167 166v-145q0 -17 -12 -29.5t-29 -12.5h-500q-17 0 -29.5 12.5t-12.5 29.5v416q0 17 12.5 29.5t29.5 12.5h500q17 0 29 -12.5t12 -29.5v-145z" />
<glyph glyph-name="uni202C" unicode="pdf"
d="M542 375h229l-229 229v-229zM250 667h333l251 -250v-501q0 -35 -24.5 -59t-59.5 -24h-500q-35 0 -59.5 24.5t-24.5 58.5v668q0 35 24.5 59t59.5 24zM455 232q26 -58 64 -90l17 -13q-27 -5 -63 -14.5t-76 -24.5v0l-5 -2l21 44q29 55 42 100zM726 73q9 9 11 27q1 13 -5 23
q-17 29 -95 29l-54 -3l-36 24q-41 35 -67 107l2 6q5 21 9.5 43t5.5 42t-2 37.5t-14 27.5q-9 10 -25 10h-10q-12 0 -21 -10t-12 -22q-6 -21 -7 -38t0.5 -32.5t5.5 -31t10 -34.5v-1q-8 -28 -18.5 -59t-26.5 -63l-40 -75l-37 -21q-38 -23 -56.5 -47t-22.5 -41q-1 -12 3 -22
l1 -3l20 -13l18 -4q26 0 55.5 31t68.5 97l7 3q32 11 73.5 18t95.5 13q32 -16 66.5 -23.5t58.5 -7.5q25 0 38 13zM709 102l3 -4q0 -5 -4 -6h-1h-8q-14 0 -35 5t-44 16q3 4 9 4q45 0 60.5 -5.5t19.5 -9.5zM326 42q-40 -74 -70 -84q2 12 14.5 31t35.5 40zM452 330q-8 28 -8 50
t5 35l3 5l6 -2q10 -14 4 -46l-1 -6l-7 -35z" />
d="M542 375h229l-229 229v-229zM250 667h333l251 -250v-501q0 -35 -24.5 -59t-59.5 -24h-500q-35 0 -59.5 24.5t-24.5 58.5v668q0 35 24.5 59t59.5 24zM455 232q26 -58 64 -90l17 -13q-27 -5 -63 -14.5t-76 -24.5v0l-5 -2l21 44q29 55 42 100zM726 73q5 5 7.5 12t3.5 15
q1 13 -5 23q-17 29 -95 29l-54 -3l-36 24q-20 17 -37 44.5t-30 62.5l2 6q5 21 9.5 43t5.5 42t-2 37.5t-14 27.5q-9 10 -25 10h-10q-12 0 -21 -10t-12 -22q-6 -21 -7 -38t0.5 -32.5t5.5 -31t10 -34.5v-1q-8 -28 -18.5 -59t-26.5 -63l-40 -75l-37 -21q-38 -23 -56.5 -47
t-22.5 -41q-1 -12 3 -22l1 -3l20 -13l18 -4q26 0 55.5 31t68.5 97l7 3q32 11 73.5 18t95.5 13q32 -16 66.5 -23.5t58.5 -7.5q25 0 38 13zM709 102l3 -4q0 -5 -4 -6h-1h-8q-14 0 -35 5t-44 16q3 4 9 4q44 0 60 -5.5t20 -9.5zM326 42q-20 -38 -38 -58.5t-32 -25.5
q2 12 14.5 31t35.5 40zM452 330q-8 28 -8 50t5 35l3 5l6 -2q10 -14 4 -46l-1 -6l-7 -35z" />
<glyph glyph-name="text" unicode="text"
d="M625 42h-500v83h500v-83zM625 375h-500v83h500v-83zM125 292h750v-84h-750v84zM125 -42h750v-83h-750v83zM875 625v-83h-750v83h750z" />
<glyph glyph-name="audio" unicode="audio"
@ -162,8 +162,9 @@ d="M875 -42q0 -35 -24.5 -59t-58.5 -24h-584q-34 0 -58.5 24.5t-24.5 58.5v584q0 35
<glyph glyph-name="gallery" unicode="gallery"
d="M917 83q0 -35 -24.5 -59t-58.5 -24h-501q-35 0 -59 24t-24 59v501q0 34 24 58.5t59 24.5h501q34 0 58.5 -24.5t24.5 -58.5v-501zM333 83h501l-167 209l-124 -155l-85 113zM166 500v-584h584v-83h-584q-34 0 -58.5 24.5t-24.5 58.5v584h83z" />
<glyph glyph-name="user" unicode="user"
d="M500 185q44 0 105 -11t116.5 -33t94 -55.5t38.5 -77.5v-133h-708v133q0 44 38.5 77.5t94 55.5t116.5 33t105 11zM500 583q37 0 69 -14t56 -38t38 -56t14 -69t-14 -69t-38 -56t-56 -38t-69 -14t-69 14t-56 38t-38 56t-14 69t14 69t38 56t56 38t69 14zM500 101
q-50 0 -98.5 -10.5t-86.5 -25.5t-61.5 -30.5t-23.5 -26.5v-49h540v49q0 11 -24 26.5t-62 30.5t-86.5 25.5t-97.5 10.5zM500 499q-38 0 -65.5 -27.5t-27.5 -65.5v0q0 -38 27.5 -65.5t65.5 -27.5v0q38 0 65.5 27.5t27.5 65.5v0q0 38 -27.5 65.5t-65.5 27.5v0z" />
d="M500 185q30 0 67.5 -5t77 -14.5t77 -24.5t67 -34.5t47.5 -44.5t18 -54v-133h-708v133q0 30 18 54.5t47.5 44t67 34.5t77 24.5t77 14.5t67.5 5zM500 583q37 0 69 -14t56 -38t38 -56t14 -69t-14 -69t-38 -56t-56 -38t-69 -14t-69 14t-56 38t-38 56t-14 69t14 69t38 56
t56 38t69 14zM500 101q-50 0 -98.5 -10.5t-86.5 -25.5t-61.5 -30.5t-23.5 -26.5v-49h540v49q0 11 -24 26.5t-62 30.5t-86.5 25.5t-97.5 10.5zM500 499q-19 0 -36 -7.5t-29.5 -20t-20 -29.5t-7.5 -36v0q0 -19 7.5 -36t20 -29.5t29.5 -20t36 -7.5v0q19 0 36 7.5t29.5 20
t20 29.5t7.5 36v0q0 19 -7.5 36t-20 29.5t-29.5 20t-36 7.5v0z" />
<glyph glyph-name="notifications" unicode="notifications"
d="M500 -167q-35 0 -59 24.5t-24 58.5h166q0 -34 -24 -58.5t-59 -24.5zM833 0v-42h-666v42l83 83v208q0 48 12.5 91t36.5 78t59 59.5t80 34.5v28q0 26 18 44.5t44 18.5t44 -18.5t18 -44.5v-28q45 -10 80 -34.5t59 -59.5t36.5 -78t12.5 -91v-208zM667 291q0 39 -11.5 73
t-33 59.5t-52.5 40t-70 14.5t-70 -14.5t-52 -40t-32.5 -59.5t-11.5 -73v-250h333v250z" />
@ -172,10 +173,10 @@ d="M792 209h-250v-250h-84v250h-250v84h250v250h84v-250h250v-84z" />
<glyph glyph-name="menu" unicode="menu"
d="M125 83h750v-83h-750v83zM125 292h750v-84h-750v84zM875 500v-83h-750v83h750z" />
<glyph glyph-name="heartfill" unicode="heartfill"
d="M83 396q0 48 18 90t49 73t73 48.5t90 17.5q54 0 103.5 -23.5t83.5 -63.5q34 40 83.5 63.5t104.5 23.5q48 0 90 -17.5t72.5 -48.5t48.5 -73t18 -90q0 -59 -25.5 -114t-72.5 -112t-112.5 -119.5t-146.5 -135.5l-60 -55l-60 55q-81 73 -146.5 135.5t-112.5 119.5t-72.5 112
t-25.5 114z" />
d="M500 -140l-60 55q-81 73 -146.5 135.5t-112.5 119.5t-72.5 112t-25.5 114q0 48 18 90t49 73t73 48.5t90 17.5q54 0 103.5 -23.5t83.5 -63.5q34 40 83.5 63.5t104.5 23.5q48 0 90 -17.5t72.5 -48.5t48.5 -73t18 -90q0 -59 -25.5 -114t-72.5 -112t-112.5 -119.5
t-146.5 -135.5z" />
<glyph glyph-name="uni22C6" unicode="star"
d="M83 365l300 26l117 276l117 -276l300 -26l-228 -197l69 -293l-258 155l-257 -155l67 293z" />
d="M243 -125l67 293l-227 197l300 26l117 276l117 -276l300 -26l-228 -197l69 -293l-258 155z" />
<glyph glyph-name="viewtable" unicode="viewtable"
d="M249 501h-125v-125h125v125zM916 376h-583v125h583v-125zM249 167h-125v126h125v-126zM916 167h-583v126h583v-126zM249 -41h-125v125h125v-125zM916 -41h-583v125h583v-125z" />
<glyph glyph-name="viewcards" unicode="viewcards"
@ -193,25 +194,25 @@ d="M667 416h-167v84h167v-84zM792 166h-292v84h292v-84zM917 -84h-417v83h417v-83zM2
<glyph glyph-name="viewrecords" unicode="viewrecords"
d="M333 543h-208v-584h208v584zM625 -41h-208v584h208v-584zM917 -41h-208v584h208v-584z" />
<glyph glyph-name="close" unicode="close"
d="M441 251l-233 233l59 59l233 -233l233 233l59 -59l-233 -233l233 -233l-59 -59l-233 233l-233 -233l-59 59z" />
d="M559 251l233 -233l-59 -59l-233 233l-233 -233l-59 59l233 233l-233 233l59 59l233 -233l233 233l59 -59z" />
<glyph glyph-name="heartoutline" unicode="heartoutline"
d="M313 625q54 0 103.5 -23.5t83.5 -63.5q34 40 83.5 63.5t104.5 23.5q48 0 90 -17.5t72.5 -48.5t48.5 -73t18 -90q0 -59 -25.5 -114t-72.5 -112t-112.5 -119.5t-146.5 -135.5l-60 -55l-60 55q-81 73 -146.5 135.5t-112.5 119.5t-72.5 112t-25.5 114q0 48 18 90t49 73
t73 48.5t90 17.5zM461 443q-17 43 -58.5 71t-89.5 28q-31 0 -58 -11t-46.5 -30.5t-30.5 -46.5t-11 -58q0 -45 23.5 -91t66.5 -96.5t103.5 -107t134.5 -124.5l5 -4l4 4q75 68 135.5 124.5t103.5 107t66.5 96.5t23.5 91q0 63 -41 104.5t-104 41.5q-49 0 -90.5 -28t-58.5 -71
h-78z" />
d="M504 -23q75 68 135.5 124.5t103.5 107t66.5 96.5t23.5 91q0 31 -11 58t-30.5 46.5t-46 30.5t-57.5 11q-24 0 -47.5 -7.5t-43 -20.5t-35 -31.5t-23.5 -39.5h-78q-8 21 -23.5 39.5t-35 31.5t-42.5 20.5t-47 7.5q-31 0 -58 -11t-46.5 -30.5t-30.5 -46.5t-11 -58
q0 -45 23.5 -91t66.5 -96.5t103.5 -107t134.5 -124.5l5 -4zM688 625q48 0 90 -17.5t72.5 -48.5t48.5 -73t18 -90q0 -59 -25.5 -114t-72.5 -112t-112.5 -119.5t-146.5 -135.5l-60 -55l-60 55q-81 73 -146.5 135.5t-112.5 119.5t-72.5 112t-25.5 114q0 48 18 90t49 73t73 48.5
t90 17.5q54 0 103.5 -23.5t83.5 -63.5q34 40 83.5 63.5t104.5 23.5z" />
<glyph glyph-name="wordpress" unicode="wordpress"
d="M500 669q-86 0 -162 -33t-132.5 -89t-89.5 -131.5t-33 -161.5t32.5 -162t89 -133t131.5 -90t160 -34q87 -1 163 31.5t133 89t90.5 132.5t34.5 161t-31 161t-88 133.5t-132.5 91.5t-165.5 34zM898 251q0 -82 -32 -154.5t-86.5 -126.5t-127.5 -85.5t-156 -30.5
q-81 1 -153 32.5t-126 86.5t-84.5 128t-29.5 157q1 81 33 153t86.5 125.5t127.5 84t156 29.5q82 -1 153.5 -33.5t124.5 -86.5t83.5 -126t30.5 -153zM682 45q-1 -2 -1.5 -4t-2.5 -5q-32 97 -64.5 192t-64.5 191q11 1 20.5 2t18.5 2q16 2 16 15q-2 15 -18 14l-42 -2t-42 -1
q-21 -1 -42 0t-41 2q-5 0 -10.5 0.5t-10.5 0.5q-13 0 -15 -14q0 -13 14 -15q8 -1 15.5 -1.5t15.5 -1.5q6 0 8 -6q13 -35 26 -71l26 -72q2 -4 0 -8q-19 -57 -37.5 -113t-37.5 -113q0 -1 -0.5 -1.5t-1.5 -2.5q-33 97 -65.5 193t-64.5 193q10 1 19.5 2t18.5 2q18 2 16 16
q0 15 -17 13q-22 -1 -43.5 -2t-43.5 -2h-30q44 63 101 102t131 53q171 31 309 -87q-43 0 -60 -38q-12 -28 1 -56q10 -23 26 -47q15 -25 24 -51.5t8 -55.5q0 -20 -5 -40t-11 -40q-11 -35 -21.5 -71t-21.5 -72zM505 218h2q28 -76 55.5 -151.5t55.5 -152.5q-109 -36 -219 -5
q27 78 53.5 154.5t52.5 154.5zM166 123q-50 136 7 275q44 -118 86 -233.5t85 -232.5q-21 5 -47.5 24t-51.5 46t-46 58.5t-33 62.5zM847 167q-36 -145 -166 -222q5 14 9.5 28t9.5 28q22 64 43.5 127.5t44.5 127.5q8 23 16 46.5t10 48.5q2 17 2 34t1 34q63 -122 30 -252z" />
d="M500 666q86 0 161.5 -33t132 -89.5t89.5 -132t33 -161.5t-33 -161.5t-89.5 -132t-132 -89.5t-161.5 -33t-161.5 33t-132 89.5t-89.5 132t-33 161.5t33 161.5t89.5 132t132 89.5t161.5 33zM126 250q0 -55 15.5 -106.5t43 -95t66.5 -78t86 -57.5l-179 489
q-15 -35 -23.5 -73t-8.5 -79zM500 -124q66 0 124 21q-2 4 -2 5l-115 315l-113 -326q51 -15 106 -15zM687 23l37 125q12 39 20 68t8 53q0 35 -9.5 59.5t-20.5 43.5q-14 23 -25.5 44t-11.5 44q0 30 19.5 48t48.5 18q-51 46 -115.5 72t-137.5 26q-99 0 -180.5 -46t-132.5 -123
q32 0 62.5 1.5t61.5 3.5q8 0 12 -4.5t4.5 -10t-2.5 -10.5t-11 -6l-13 -1q-6 -1 -14 -1.5t-16 -1.5l136 -405l82 246l-58 159q-8 1 -15 1.5t-13 1.5q-6 0 -12 1q-7 0 -10.5 5t-3 11t5 10.5t11.5 4.5l36 -2q15 -2 31.5 -2.5t30.5 -0.5q15 0 32.5 0.5t32.5 2.5q17 1 35 2
q8 0 12 -4.5t4 -10t-3 -10.5t-11 -6q-6 -1 -13 -1q-5 -1 -13 -1.5t-16 -1.5zM828 429q3 -16 3 -38q0 -29 -6 -61.5t-23 -72.5l-114 -330q42 24 76 58.5t58.5 76t38 89t13.5 99.5q0 49 -12 94t-34 85z" />
<glyph glyph-name="drag" unicode="drag"
d="M292 543q0 35 -24 59t-59 24t-59.5 -24t-24.5 -59t24.5 -59.5t59.5 -24.5t59 24.5t24 59.5zM500 626q35 0 59 -24t24 -59t-24 -59.5t-59 -24.5t-59.5 24.5t-24.5 59.5t24.5 59t59.5 24zM792 626q35 0 59 -24t24 -59t-24 -59.5t-59 -24.5t-59.5 24.5t-24.5 59.5t24.5 59
t59.5 24zM209 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59t24.5 59.5t59.5 24.5zM500 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59t24.5 59.5t59.5 24.5zM792 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59
t24.5 59.5t59.5 24.5zM209 42q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59t24.5 59.5t59.5 24.5zM500 42q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59t24.5 59.5t59.5 24.5zM792 42q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24
t-24.5 59t24.5 59.5t59.5 24.5z" />
d="M292 543q0 35 -24 59t-59 24q-18 0 -33 -6.5t-26.5 -17.5t-18 -26.5t-6.5 -32.5q0 -35 24.5 -59.5t59.5 -24.5q17 0 32.5 6.5t26.5 18t17.5 26.5t6.5 33zM500 626q35 0 59 -24t24 -59q0 -18 -6.5 -33t-17.5 -26.5t-26.5 -18t-32.5 -6.5q-35 0 -59.5 24.5t-24.5 59.5
q0 17 6.5 32.5t18 26.5t26.5 17.5t33 6.5zM792 626q35 0 59 -24t24 -59q0 -18 -6.5 -33t-17.5 -26.5t-26.5 -18t-32.5 -6.5q-35 0 -59.5 24.5t-24.5 59.5q0 17 6.5 32.5t18 26.5t26.5 17.5t33 6.5zM209 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24q-18 0 -33 6.5t-26.5 18
t-18 26.5t-6.5 32t6.5 32.5t18 27t26.5 18t33 6.5zM500 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24q-18 0 -33 6.5t-26.5 18t-18 26.5t-6.5 32t6.5 32.5t18 27t26.5 18t33 6.5zM792 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24q-18 0 -33 6.5t-26.5 18t-18 26.5t-6.5 32
t6.5 32.5t18 27t26.5 18t33 6.5zM209 42q17 0 32.5 -6.5t26.5 -18t17.5 -26.5t6.5 -33q0 -35 -24 -59t-59 -24q-18 0 -33 6.5t-26.5 17.5t-18 26.5t-6.5 32.5q0 35 24.5 59.5t59.5 24.5zM500 42q17 0 32.5 -6.5t26.5 -18t17.5 -26.5t6.5 -33q0 -35 -24 -59t-59 -24
q-18 0 -33 6.5t-26.5 17.5t-18 26.5t-6.5 32.5q0 35 24.5 59.5t59.5 24.5zM792 42q17 0 32.5 -6.5t26.5 -18t17.5 -26.5t6.5 -33q0 -35 -24 -59t-59 -24q-18 0 -33 6.5t-26.5 17.5t-18 26.5t-6.5 32.5q0 35 24.5 59.5t59.5 24.5z" />
<glyph glyph-name="addcollection" unicode="addcollection"
d="M620 -22q-8 27 -10 60h-467v418h-60v-418q0 -25 17.5 -42.5t42.5 -17.5h477zM740 516q25 0 42.5 -17.5t17.5 -42.5v-227q-63 0 -112.5 -37t-67.5 -95h-358q-25 0 -42 17.5t-17 42.5v359q0 25 17 42t42 17h180l59 -59h239zM917 39q0 49 -34 83t-83 34q-24 0 -45.5 -9
t-37 -25t-25 -37.5t-9.5 -45.5t9.5 -45.5t25 -37t37 -25t45.5 -9.5t45.5 9.5t37.5 25t25 37t9 45.5zM870 22h-52v-53h-35v53h-53v35h53v52h35v-52h52v-35z" />
d="M620 -22q-8 27 -10 60h-467v418h-60v-418q0 -25 17.5 -42.5t42.5 -17.5h477zM740 516q25 0 42.5 -17.5t17.5 -42.5v-227q-31 0 -60 -10t-52.5 -27.5t-41 -41.5t-26.5 -53h-358q-25 0 -42 17.5t-17 42.5v359q0 25 17 42t42 17h180l59 -59h239zM917 39q0 24 -9 45.5
t-25 37.5t-37.5 25t-45.5 9t-45.5 -9t-37 -25t-25 -37.5t-9.5 -45.5t9.5 -45.5t25 -37t37 -25t45.5 -9.5t45.5 9.5t37.5 25t25 37t9 45.5zM870 22h-52v-53h-35v53h-53v35h53v52h35v-52h52v-35z" />
<glyph glyph-name="stop" unicode="stop"
d="M500 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89.5t162 33zM500 -83q69 0 129.5 26t106 71.5t71.5 106t26 129.5t-26 129.5t-71.5 106
t-106 71.5t-129.5 26t-129.5 -26t-106 -71.5t-71.5 -106t-26 -129.5t26 -129.5t71.5 -106t106 -71.5t129.5 -26zM667 417h-334v-334h334v334z" />
@ -232,6 +233,11 @@ d="M792 250h83v-292q0 -35 -24 -59t-59 -24h-584q-35 0 -59 24t-24 59v584q0 34 24 5
<glyph glyph-name="waiting" unicode="waiting"
d="M500 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33q-87 0 -163 33t-132.5 89.5t-89 132.5t-32.5 162t32.5 162t89 132.5t132.5 89.5t163 33zM500 -84q69 0 130 26.5t106 71.5t71.5 106t26.5 130t-26.5 130t-71.5 106
t-106 71.5t-130 26.5t-130 -26.5t-106 -71.5t-71.5 -106t-26.5 -130t26.5 -130t71.5 -106t106 -71.5t130 -26.5zM521 240l188 -112l-32 -51l-219 131v250h63v-218z" />
<glyph glyph-name="twitter" unicode="twitter"
d="M936 500q-37 -56 -89 -93v-23q0 -89 -33.5 -179.5t-98 -164t-159.5 -119.5t-218 -46q-76 0 -145 21t-129 59q11 -1 21.5 -1.5t21.5 -0.5q63 0 119.5 20t102.5 57q-60 1 -105 35.5t-62 88.5q8 -2 16.5 -3t16.5 -1q26 0 47 7q-30 6 -56.5 22t-45.5 39t-30 52.5t-11 62.5
q18 -9 38.5 -14.5t42.5 -5.5q-36 23 -57.5 62t-21.5 86q0 24 6.5 46.5t17.5 42.5q66 -81 161 -131t207 -55q-4 17 -4 41q0 37 14 69.5t38 56.5t56.5 38t69.5 14q80 0 131 -56q31 6 59.5 17t54.5 26q-22 -65 -79 -99q27 4 53 11t50 18z" />
<glyph glyph-name="facebook" unicode="facebook"
d="M707 668v-167h-83q-22 0 -32 -20.5t-10 -41.5v-105h125v-166h-125v-334h-166v334h-125v166h125v167q0 35 13 65t35.5 53t53 36t64.5 13h125z" />
<glyph glyph-name=".notdef" horiz-adv-x="500"
/>
<glyph glyph-name="uni0000" horiz-adv-x="0"
@ -240,54 +246,56 @@ t-106 71.5t-130 26.5t-130 -26.5t-106 -71.5t-71.5 -106t-26.5 -130t26.5 -130t71.5
/>
<glyph glyph-name="uni000D" unicode="&#xd;" horiz-adv-x="250"
/>
<glyph glyph-name="uni0020" unicode=" " horiz-adv-x="250"
<glyph glyph-name="space" unicode=" " horiz-adv-x="250"
/>
<glyph glyph-name="uni0072" unicode="r" horiz-adv-x="308"
<glyph glyph-name="r" unicode="r" horiz-adv-x="308"
/>
<glyph glyph-name="uni0065" unicode="e" horiz-adv-x="512"
<glyph glyph-name="e" unicode="e" horiz-adv-x="512"
/>
<glyph glyph-name="uni0070" unicode="p" horiz-adv-x="549"
<glyph glyph-name="p" unicode="p" horiz-adv-x="549"
/>
<glyph glyph-name="uni006F" unicode="o" horiz-adv-x="531"
<glyph glyph-name="o" unicode="o" horiz-adv-x="531"
/>
<glyph glyph-name="uni0073" unicode="s" horiz-adv-x="465"
<glyph glyph-name="s" unicode="s" horiz-adv-x="465"
/>
<glyph glyph-name="uni0069" unicode="i" horiz-adv-x="204"
<glyph glyph-name="i" unicode="i" horiz-adv-x="204"
/>
<glyph glyph-name="uni0074" unicode="t" horiz-adv-x="301"
<glyph glyph-name="t" unicode="t" horiz-adv-x="301"
/>
<glyph glyph-name="uni0079" unicode="y" horiz-adv-x="486"
<glyph glyph-name="y" unicode="y" horiz-adv-x="486"
/>
<glyph glyph-name="uni0063" unicode="c" horiz-adv-x="501"
<glyph glyph-name="c" unicode="c" horiz-adv-x="501"
/>
<glyph glyph-name="uni006C" unicode="l" horiz-adv-x="204"
<glyph glyph-name="l" unicode="l" horiz-adv-x="204"
/>
<glyph glyph-name="uni006E" unicode="n" horiz-adv-x="527"
<glyph glyph-name="n" unicode="n" horiz-adv-x="527"
/>
<glyph glyph-name="uni003F" unicode="?"
<glyph glyph-name="question" unicode="?"
d="M460 81h81v-81h-81v81zM514 540q54 -2 92 -28t55 -64t11.5 -83t-37.5 -86q-17 -20 -39.5 -35t-36.5 -32t-16 -37t-2 -40h-81q0 34 2 62t16 48t36.5 33.5t39.5 27.5q25 23 34 48.5t4 48t-25 38t-53 18.5q-34 0 -57.5 -23.5t-23.5 -57.5h-81q0 34 12.5 63.5t34.5 51.5
t51.5 34.5t63.5 12.5z" />
<glyph glyph-name="uni006D" unicode="m" horiz-adv-x="803"
<glyph glyph-name="m" unicode="m" horiz-adv-x="803"
/>
<glyph glyph-name="uni0061" unicode="a" horiz-adv-x="502"
<glyph glyph-name="a" unicode="a" horiz-adv-x="502"
/>
<glyph glyph-name="uni0064" unicode="d" horiz-adv-x="554"
<glyph glyph-name="d" unicode="d" horiz-adv-x="554"
/>
<glyph glyph-name="uni0078" unicode="x" horiz-adv-x="469"
<glyph glyph-name="x" unicode="x" horiz-adv-x="469"
/>
<glyph glyph-name="uni0076" unicode="v" horiz-adv-x="483"
<glyph glyph-name="v" unicode="v" horiz-adv-x="483"
/>
<glyph glyph-name="uni0066" unicode="f" horiz-adv-x="304"
<glyph glyph-name="f" unicode="f" horiz-adv-x="304"
/>
<glyph glyph-name="uni0077" unicode="w" horiz-adv-x="715"
<glyph glyph-name="w" unicode="w" horiz-adv-x="715"
/>
<glyph glyph-name="uni0075" unicode="u" horiz-adv-x="527"
<glyph glyph-name="u" unicode="u" horiz-adv-x="527"
/>
<glyph glyph-name="uni0067" unicode="g" horiz-adv-x="549"
<glyph glyph-name="g" unicode="g" horiz-adv-x="549"
/>
<glyph glyph-name="uni0068" unicode="h" horiz-adv-x="539"
<glyph glyph-name="h" unicode="h" horiz-adv-x="539"
/>
<glyph glyph-name="uni0062" unicode="b" horiz-adv-x="554"
<glyph glyph-name="b" unicode="b" horiz-adv-x="554"
/>
<glyph glyph-name="k" unicode="k" horiz-adv-x="534"
/>
</font>
</defs></svg>

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -273,6 +273,12 @@
.tainacan-icon-viewtable:before {
content: "viewtable";
}
.tainacan-icon-facebook:before {
content: "facebook";
}
.tainacan-icon-twitter:before {
content: "twitter";
}
.tainacan-icon-18px.tainacan-icon-set,
.tainacan-icon-18px.tainacan-icon:before {

View File

@ -7,6 +7,8 @@ namespace Tainacan;
class Media {
private static $instance = null;
private static $file_handle = null;
private static $file_name = null;
public static function get_instance() {
if(!isset(self::$instance)) {
@ -29,18 +31,13 @@ class Media {
* @return Int|false Attachment ID. False on failure
*/
public function insert_attachment_from_url($url, $post_id = null) {
if( !class_exists( '\WP_Http' ) )
include_once( ABSPATH . WPINC . '/class-http.php' );
$filename = $this->save_remote_file($url);
$http = new \WP_Http();
$response = $http->request( $url, ['sslverify' => false] );
if( !is_array($response) || !isset($response['response']) || $response['response']['code'] != 200 ) {
return false;
}
return $this->insert_attachment_from_blob($response['body'], basename($url), $post_id);
if( !file_exists($filename) ) {
return false;
}
return $this->insert_attachment_from_blob(fopen($filename,'r'), basename($url), $post_id);
}
@ -57,11 +54,62 @@ class Media {
return false;
}
return $this->insert_attachment_from_blob(file_get_contents($filename), basename($filename), $post_id);
return $this->insert_attachment_from_blob(fopen($filename,'r'), basename($filename), $post_id);
}
/**
/**
* Avoid memory overflow problems with large files (Exceeded maximum memory limit of PHP)
*
* @param $url
* @return string the file path
*/
public function save_remote_file($url) {
set_time_limit(0);
$filename = tempnam(sys_get_temp_dir(), basename($url));
# Open the file for writing...
self::$file_handle = fopen($filename, 'w+');
self::$file_name = $filename;
$callback = function ($ch, $str) {
$len = fwrite(self::$file_handle, $str);
return $len;
};
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FILE, self::$file_handle);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); # optional
curl_setopt($ch, CURLOPT_TIMEOUT, -1); # optional: -1 = unlimited, 3600 = 1 hour
curl_setopt($ch, CURLOPT_VERBOSE, false); # Set to true to see all the innards
# Only if you need to bypass SSL certificate validation
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
# Assign a callback function to the CURL Write-Function
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback);
# Exceute the download - note we DO NOT put the result into a variable!
curl_exec($ch);
# Close CURL
curl_close($ch);
# Close the file pointer
fclose(self::$file_handle);
return $filename;
}
/**
* Insert an attachment from an URL address.
*
* @param blob $blob bitstream of the attachment
@ -76,6 +124,13 @@ class Media {
return false;
}
if( @filesize($upload['file']) == 0 && is_resource($blob) ){
$file_wordpress_stream = fopen( $upload['file'], 'r+');
stream_copy_to_stream($blob, $file_wordpress_stream);
if( file_exists(self::$file_name) ) unlink(self::$file_name);
}
$file_path = $upload['file'];
$file_name = basename( $file_path );
$file_type = wp_check_filetype( $file_name, null );

View File

@ -313,7 +313,7 @@ class Item_Metadata_Entity extends Entity {
return $this->has_value;
$value = $this->get_value();
$this->has_value = !empty($value);
$this->has_value = (is_array($value)) ? !empty(array_filter($value)) : !empty($value);
return $this->has_value;
}

View File

@ -223,7 +223,7 @@ class Term extends Entity {
$term_exists = $repo->term_exists($name, $taxonomy, $parent, true);
if (false !== $term_exists) {
if ($this->get_id() != $term_exists->term_taxonomy_id) {
if ($this->get_id() != $term_exists->term_id) {
$this->add_error( 'repeated', __('You can not have two terms with the same name at the same level', 'tainacan') );
return false;
}

View File

@ -72,8 +72,8 @@
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('label_add_value') }}</a>
&nbsp;{{ $i18n.get('label_add_value') }}
</a>
</div>
</div>
</transition>
@ -230,7 +230,8 @@
.multiple-inputs {
display: flex;
align-items: center;
margin: 0.75rem 0;
flex-direction: column;
justify-content: space-between;
}

View File

@ -1,14 +1,14 @@
<template>
<div>
<span v-if="!showForm">
<a
@click="toggleForm()"
class="is-inline add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('label_new_term') }}</a>
<a
@click="toggleForm()"
class="is-inline add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('label_new_term') }}
</a>
</span>
<transition name="appear">
<section

View File

@ -117,6 +117,16 @@ class Taxonomy extends Metadata_Type {
$Tainacan_Metadata = Metadata::get_instance();
// Check taxonomy visibility
$status = get_post_status( $this->get_option('taxonomy_id') );
$post_status_obj = get_post_status_object($status);
if ( ! $post_status_obj->public ) {
$meta_status_obj = get_post_status_object($metadatum->get_status());
if ( $meta_status_obj->public ) {
return ['taxonomy_id' => __('This metadatum can not be public because chosen taxonomy is not.', 'tainacan')];
}
}
$taxonomy_metadata = $Tainacan_Metadata->fetch([
'collection_id' => $metadatum->get_collection_id(),
'metadata_type' => 'Tainacan\\Metadata_Types\\Taxonomy'

View File

@ -297,8 +297,9 @@ class Item_Metadata extends Repository {
} elseif ( $metadata_type->get_primitive_type() == 'term' ) {
if ( is_numeric( $metadata_type->get_option( 'taxonomy_id' ) ) ) {
$taxonomy = new Entities\Taxonomy( $metadata_type->get_option( 'taxonomy_id' ) );
if ( $taxonomy ) {
//$taxonomy = new Entities\Taxonomy( $metadata_type->get_option( 'taxonomy_id' ) );
$taxonomy = Taxonomies::get_instance()->fetch( (int) $metadata_type->get_option( 'taxonomy_id' ) );
if ( $taxonomy instanceof Entities\Taxonomy && $taxonomy->can_read() ) {
$taxonomy_slug = $taxonomy->get_db_identifier();
} else {
return null;

View File

@ -227,7 +227,12 @@ class Items extends Repository {
}
if ( empty( $collections ) ) {
$collections = $Tainacan_Collections->fetch( [], 'OBJECT' );
$post_types = get_post_types();
$collections = array_map( function($el) use ($Tainacan_Collections) {
if ( $id = $Tainacan_Collections->get_id_by_db_identifier($el) ) {
return $id;
}
} , $post_types);
}
if ( is_numeric( $collections ) ) {

View File

@ -575,6 +575,8 @@ class CSV extends Importer {
$tainacan_metadatum_id = array_search( $metadatum_source, $collection_definition['mapping'] );
$metadatum = $Tainacan_Metadata->fetch( $tainacan_metadatum_id );
if( $this->is_empty_value( $values ) ) continue;
if( $metadatum instanceof Entities\Metadatum ) {
$singleItemMetadata = new Entities\Item_Metadata_Entity( $item, $metadatum); // *empty item will be replaced by inserted in the next foreach
if( $metadatum->get_metadata_type() == 'Tainacan\Metadata_Types\Taxonomy' ) {
@ -648,7 +650,19 @@ class CSV extends Importer {
return false;
}
}
/**
* @param $value
* @return bool
*/
public function is_empty_value( $value ){
if( is_array( $value ) ){
return ( empty( array_filter( $value ) ) );
} else {
return ( trim( $value ) === '' );
}
}
/**
* @param $metadatum the metadata
* @param $values the categories names
@ -663,14 +677,19 @@ class CSV extends Importer {
$Tainacan_Terms = \Tainacan\Repositories\Terms::get_instance();
$taxonomy = new Entities\Taxonomy( $metadatum->get_metadata_type_options()['taxonomy_id']);
$exploded_values = explode(">>",$values);
if ( strpos($values, '>>') === false ) {
return $values;
}
$exploded_values = explode(">>",$values);
if (empty($exploded_values)) {
return false;
}
if( is_array($exploded_values) ) {
$parent = ( count($exploded_values) === 1 ) ? null : 0;
$parent = 0;
foreach ( $exploded_values as $key => $value) {
$value = trim($value);
if ($value=='') {
@ -678,8 +697,8 @@ class CSV extends Importer {
return false;
}
$exists = $Tainacan_Terms->term_exists( $value ,$taxonomy->get_db_identifier(), $parent, true );
if (false !== $exists && isset($exists->term_taxonomy_id)) {
$parent = $exists->term_taxonomy_id;
if (false !== $exists && isset($exists->term_id)) {
$parent = $exists->term_id;
} else {
$this->add_log('New term created: ' . $value . ' in tax_id: ' . $taxonomy->get_db_identifier() . '; parent: ' . $parent);
$term = new Entities\Term();

View File

@ -61,6 +61,15 @@ class Importer_Handler {
'manual_mapping' => false,
]);
// $this->register_importer([
// 'name' => 'Youtube (Experimental)',
// 'description' => __('Import items from an Youtube URL', 'tainacan'),
// 'slug' => 'youtube_importer',
// 'class_name' => '\Tainacan\Importer\Youtube_Importer',
// 'manual_collection' => true,
// 'manual_mapping' => false,
// ]);
do_action('tainacan_register_importers');
add_action( 'tainacan-enqueue-admin-scripts', array($this, 'enqueue_scripts') );

View File

@ -720,6 +720,10 @@ abstract class Importer {
$current_collection_item ++;
$this->set_current_collection_item($current_collection_item);
if( $this->get_transient('change_total') ){
$collection['total_items'] = $this->get_transient('change_total');
}
if ($current_collection_item >= $collection['total_items']) {
return $this->next_collection();

View File

@ -21,6 +21,8 @@ class Oaipmh_Importer extends Importer {
protected $NAME_FOR_SETS = 'Sets';
protected $tainacan_api_address, $wordpress_api_address, $actual_collection;
protected $has_sets = true;
protected $items_per_page = 100;
/**
* tainacan old importer construct
@ -54,7 +56,7 @@ class Oaipmh_Importer extends Importer {
if( $index === 0 ){
if( $collection_id['source_id'] !== 'sets' ){
if( $collection_id['source_id'] !== 'sets' && $this->has_sets ){
$info = $this->requester( $this->get_url() . "?verb=ListRecords&metadataPrefix=oai_dc&set=" . $collection_id['source_id'] );
$this->add_log('fetching ' . $this->get_url() . "?verb=ListRecords&metadataPrefix=oai_dc&set=" . $collection_id['source_id']);
} else {
@ -83,6 +85,26 @@ class Oaipmh_Importer extends Importer {
if ($resumptionToken) {
$this->add_transient('resumptionToken',(string) $resumptionToken);
}
// if there is no total in resumption token and exists cursor
// it will change dynamic the total of items
$resumptionToken_attributes = $xml->ListRecords->resumptionToken->attributes();
$real_total = $this->get_transient('total_general');
foreach ($resumptionToken_attributes as $tag => $attribute) {
if ( $tag == 'cursor' && $real_total == ( (string) $attribute ) && !$this->hasCompleteSize( $resumptionToken_attributes ) ) {
$real_total = $real_total + intval($this->get_transient('items_per_page'));
$this->add_transient('total_general', $real_total);
$total = ( $this->get_transient('change_total') ) ? $this->get_transient('change_total') : 1;
$this->add_transient('change_total', $total + 1);
break;
}
}
}
} catch (Exception $e) {
@ -166,7 +188,7 @@ class Oaipmh_Importer extends Importer {
$this->add_collection([
'id' => $collection->get_id(),
'mapping' => $metadata_map,
'total_items' =>ceil( $total / 100 ),
'total_items' => ceil( $total / $this->items_per_page ),
'source_id' => $setSpec,
]);
}
@ -201,7 +223,7 @@ class Oaipmh_Importer extends Importer {
$this->add_collection([
'id' => $collection->get_id(),
'mapping' => $metadata_map,
'total_items' =>ceil( $total / 100 ),
'total_items' =>ceil( $total / $this->items_per_page ),
'source_id' => 'sets',
'metadatum_id' => $metadatum_set_id
]);
@ -226,7 +248,22 @@ class Oaipmh_Importer extends Importer {
}
}
// if there is no set
else {
$collection = $this->create_collection( 'set', $this->getRepoName() );
$metadata_map = $this->create_collection_metadata($collection);
$total = intval( $this->get_total_items_from_source(false) );
$this->add_log('total in collection: ' . $total);
$this->add_log('collection id ' . (string) $collection->get_id());
$this->add_collection([
'id' => $collection->get_id(),
'mapping' => $metadata_map,
'total_items' =>ceil( $total / $this->items_per_page ),
]);
$this->has_sets = false;
}
$resumptionToken = $this->get_transient('collection_resump');
if( $resumptionToken !== ''){
@ -290,7 +327,6 @@ class Oaipmh_Importer extends Importer {
foreach ( $record as $index => $value ){
$this->add_log( 'inserting metadata ' . $index );
if( in_array( $index, $map ) && $insertedItem->get_id()){
$metadatum_id = array_search($index, $map );
$newMetadatum = new Entities\Metadatum($metadatum_id);
@ -303,7 +339,7 @@ class Oaipmh_Importer extends Importer {
if( $item_metadata->validate() ){
$inserted = $this->item_metadata_repo->insert( $item_metadata );
$this->add_log('Item Metadata inserted for item ' .$item->get_title() . ' and metadata ' . $newMetadatum->get_name() );
// $this->add_log('Item Metadata inserted for item ' .$item->get_title() . ' and metadata ' . $newMetadatum->get_name() );
} else {
$this->add_log( 'Error inserting metadatum' . $newMetadatum->get_name() );
$this->add_log( 'Values' . $value );
@ -365,15 +401,29 @@ class Oaipmh_Importer extends Importer {
$cont = 0;
foreach ($xml->ListRecords->record as $record) $cont++;
$this->add_transient('total_general', (string) $cont );
return $cont;
} elseif ( isset($xml->ListRecords) && isset($xml->ListRecords->resumptionToken) ){
$resumptionToken_attributes = $xml->ListRecords->resumptionToken->attributes();
foreach ($resumptionToken_attributes as $tag => $attribute) {
if ($tag == 'completeListSize') {
$this->add_transient('total_general', (string) $attribute);
return (string) $attribute;
}
}
foreach ($resumptionToken_attributes as $tag => $attribute) {
if ($tag == 'cursor') {
$this->items_per_page = $attribute;
$this->add_transient('items_per_page', (string) $this->items_per_page);
}
}
// if the total is not found
$this->add_transient('total_general', (string) $this->items_per_page);
return $this->items_per_page;
}
} catch (Exception $e) {
$this->add_log('ERROR');
@ -699,7 +749,7 @@ class Oaipmh_Importer extends Importer {
try {
$xml = new \SimpleXMLElement($info['body']);
if( isset($xml->Identify) && isset($xml->Identify->repositoryName) ){
if( isset($xml->Identify) && isset($xml->Identify->repositoryName) && !empty($xml->Identify->repositoryName) ){
return (string) $xml->Identify->repositoryName;
}
} catch (Exception $e) {
@ -711,6 +761,81 @@ class Oaipmh_Importer extends Importer {
}
}
/**
* @param $attributes
* @return bool
*/
public function hasCompleteSize( $attributes ) {
foreach ( $attributes as $tag => $attribute ) {
if ( $tag == 'completeListSize' ) {
return true;
}
}
return false;
}
/**
* Gets the current value to build the progress bar and give feedback to the user
* on the background process that is running the importer.
*
* It does so by comparing the "size" attribute with the $in_step_count class attribute
* where size indicates the total size of iterations the step will take and $this->in_step_count
* is the current iteration.
*
* For the step with "process_items" as a callback, this method will look for the the $this->collections array
* and sum the value of all "total_items" attributes of each collection. Then it will look for
* $this->get_current_collection and $this->set_current_collection_item to calculate the progress.
*
* The value must be from 0 to 100
*
* If a negative value is passed, it is assumed that the progress is unknown
*/
public function get_progress_value() {
$current_step = $this->get_current_step();
$steps = $this->get_steps();
$value = -1;
if ( isset($steps[$current_step]) ) {
$step = $steps[$current_step];
if ($step['callback'] == 'process_collections') {
$totalItems = 0;
$currentItem = $this->get_current_collection_item();
$current_collection = $this->get_current_collection();
$collections = $this->get_collections();
foreach ($collections as $i => $col) {
if ( isset($col['total_items']) && is_numeric($col['total_items']) ) {
$totalItems += intval($col['total_items']);
if ($i < $current_collection) {
$currentItem += $col['total_items'];
}
}
}
if ($totalItems > 0) {
$totalItems = ($this->get_transient('change_total')) ? $this->get_transient('change_total') : $totalItems;
$value = round( ($currentItem/$totalItems) * 100 );
}
} else {
if ( isset($step['total']) && is_numeric($step['total']) && $step['total'] > 0 ) {
$total = ($this->get_transient('change_total')) ? $this->get_transient('change_total') : $step['total'];
$current = $this->get_in_step_count();
$value = round( ($current/$total) * 100 );
}
}
}
return $value;
}
public function options_form(){
ob_start();
?>

View File

@ -0,0 +1,104 @@
<?php
namespace Tainacan\Importer;
use Tainacan;
use Tainacan\Entities;
class Youtube_Importer extends Importer {
protected $steps = [
[
'name' => 'Identify URL',
'progress_label' => 'Identify URL',
'callback' => 'identify_url'
],
[
'name' => 'Import Items',
'progress_label' => 'Import Items',
'callback' => 'process_collections',
'total' => 2
],
];
/**
* construct
*/
public function __construct($attributes = array()) {
parent::__construct($attributes);
$this->col_repo = \Tainacan\Repositories\Collections::get_instance();
$this->items_repo = \Tainacan\Repositories\Items::get_instance();
$this->metadata_repo = \Tainacan\Repositories\Metadata::get_instance();
$this->item_metadata_repo = \Tainacan\Repositories\Item_Metadata::get_instance();
$this->tax_repo = \Tainacan\Repositories\Taxonomies::get_instance();
$this->term_repo = \Tainacan\Repositories\Terms::get_instance();
$this->remove_import_method('file');
$this->add_import_method('url');
}
/**
* Method implemented by the child importer class to proccess each item
* @return int
*/
public function process_item( $index, $collection_id ){
}
/**
* identify the type of url is send by user
*/
public function identify_url(){
$url = $this->get_url();
$preg_entities = [
'channel_id' => '\/channel\/(([^\/])+?)$', //match YouTube channel ID from url
'user' => '\/user\/(([^\/])+?)$', //match YouTube user from url
'playlist_id' => '\/playlist\?list=(([^\/])+?)$', //match YouTube playlist ID from url
'v' => '\'%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i\''
];
foreach ( $preg_entities as $key => $preg_entity ) {
if ( preg_match( '/' . $preg_entity . '/', $url, $matches ) ) {
if ( isset( $matches[1] ) ) {
return [
'type' => $key,
'id' => $matches[1],
];
}
}
}
}
public function options_form(){
ob_start();
?>
<div class="field">
<label class="label"><?php _e('API ID', 'tainacan'); ?></label>
<span class="help-wrapper">
<a class="help-button has-text-secondary">
<span class="icon is-small">
<i class="tainacan-icon tainacan-icon-help" ></i>
</span>
</a>
<vdiv class="help-tooltip">
<div class="help-tooltip-header">
<h5><?php _e('Youtube API ID', 'tainacan'); ?></h5>
</div>
<div class="help-tooltip-body">
<p><?php _e('Get youtube API ID if you request for channels or playlists', 'tainacan'); ?></p>
</div>
</vdiv>
</span>
<div class="control is-clearfix">
<input class="input" type="text" name="api_id" value="<?php echo $this->get_option('api_id'); ?>">
</div>
</div>
<?php
return ob_get_clean();
}
}

View File

@ -145,6 +145,54 @@ export const updateFilteTypes = ( { commit }, filterTypes) => {
commit('setFilterTypes', filterTypes);
};
// REPOSITORY COLLECTION FILTERS - MULTIPLE COLLECTIONS ------------------------
export const fetchRepositoryCollectionFilters = ({ dispatch, commit } ) => {
commit('clearRepositoryCollectionFilters');
return new Promise((resolve, reject) => {
dispatch('collection/fetchCollectionsForParent', { } ,{ root: true })
.then((res) => {
let collections = res;
if (collections != undefined && collections.length != undefined) {
let amountOfCollectionsLoaded = 0;
for (let collection of collections ) {
let endpoint = '';
endpoint = '/collection/' + collection.id + '/filters/?nopaging=1&include_disabled=no';
axios.tainacan.get(endpoint)
.then((resp) => {
let repositoryFilters = resp.data.filter((filter) => {
return (filter.collection_id == 'default' || filter.collection_id == 'filter_in_repository')
});
let collectionFilters = resp.data.filter((filter) => {
return (filter.collection_id != 'default' && filter.collection_id != 'filter_in_repository')
});
commit('setRepositoryCollectionFilters', { collectionName: collection.id, repositoryCollectionFilters: collectionFilters });
commit('setRepositoryCollectionFilters', { collectionName: undefined, repositoryCollectionFilters: repositoryFilters });
amountOfCollectionsLoaded++;
if (amountOfCollectionsLoaded == collections.length) {
resolve();
}
})
.catch((error) => {
console.log(error);
reject(error);
});
}
}
})
.error(() => {
reject();
});
});
};
// TAXONOMY FILTERS - MULTIPLE COLLECTIONS ------------------------
export const fetchTaxonomyFilters = ({ dispatch, commit }, taxonomyId ) => {

View File

@ -19,6 +19,10 @@ export const getFilterTypes = state => {
return state.filterTypes;
}
export const getRepositoryCollectionFilters = state => {
return state.repositoryCollectionFilters;
}
export const getTaxonomyFilters = state => {
return state.taxonomyFilters;
}

View File

@ -10,7 +10,8 @@ const state = {
},
filters: [],
filterTypes: [],
taxonomyFilters: {}
taxonomyFilters: {},
repositoryCollectionFilters: {}
};
export default {

View File

@ -36,6 +36,21 @@ export const setFilterTypes = (state, filterTypes) => {
state.filterTypes = filterTypes;
}
// export const setRepositoryCollectionFilters = (state, repositoryCollectionFilters) => {
// state.repositoryCollectionFilters = repositoryCollectionFilters;
// }
export const setRepositoryCollectionFilters = (state, { collectionName, repositoryCollectionFilters }) => {
if (collectionName != undefined)
Vue.set(state.repositoryCollectionFilters, collectionName, repositoryCollectionFilters);
else
Vue.set(state.repositoryCollectionFilters, 'repository-filters', repositoryCollectionFilters);
}
export const clearRepositoryCollectionFilters = (state) => {
state.repositoryCollectionFilters = {};
}
export const setTaxonomyFilters = (state, taxonomyFilters) => {
state.taxonomyFilters = taxonomyFilters;
}

View File

@ -62,9 +62,12 @@ export const setPage = ({ commit }, page ) => {
commit('setPostQueryAttribute', { attr: 'paged', value: page } );
};
export const setItemsPerPage = ({ commit }, page ) => {
commit('setPostQueryAttribute', { attr: 'perpage', value: page } );
commit('setItemsPerPage', page );
export const setItemsPerPage = ({ commit }, perPage ) => {
const maxItemsPerPage = tainacan_plugin.api_max_items_per_page;
perPage = (Number(maxItemsPerPage) >= Number(perPage)) ? perPage : maxItemsPerPage;
commit('setPostQueryAttribute', { attr: 'perpage', value: perPage } );
commit('setItemsPerPage', perPage );
};
export const setFacets = ({ commit }, facets) => {

View File

@ -46,6 +46,7 @@ class Migrations {
progress_label text,
progress_value int,
status ENUM('waiting','running','paused','cancelled','errored','finished','finished-errors'),
output longtext,
PRIMARY KEY (ID),
KEY user_id (user_id),
KEY action (action($max_index_length))

View File

@ -214,7 +214,7 @@ class Theme_Helper {
$tax_id = \Tainacan\Repositories\Taxonomies::get_instance()->get_id_by_db_identifier($term->taxonomy);
$tax = \Tainacan\Repositories\Taxonomies::get_instance()->fetch($tax_id);
if ( $tax ) {
if ( $tax && $tax->can_read() ) {
$post_types = $tax->get_enabled_post_types();
// TODO: Why post_type = any does not work?
@ -223,6 +223,9 @@ class Theme_Helper {
$post_types = array_merge($post_types, \Tainacan\Repositories\Repository::get_collections_db_identifiers());
$wp_query->set( 'post_type', $post_types);
} else {
$wp_query->set_404();
status_header( 404 );
}

View File

@ -88,8 +88,7 @@ export default {
},
data () {
return {
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
isMounted: false
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png'
}
},
methods: {
@ -121,7 +120,7 @@ export default {
this.$refs.masonryWrapper.children[0] != undefined &&
this.$refs.masonryWrapper.children[0].children[0] != undefined &&
this.$refs.masonryWrapper.children[0].children[0].clientWidth != undefined)
this.itemColumnWidth = this.$refs.masonryWrapper.children[0].children[0].clientWidth;
this.itemColumnWidth = this.$refs.masonryWrapper.children[0].children[0].clientWidth;
return (imageHeight*this.itemColumnWidth)/imageWidth;
},
@ -130,12 +129,14 @@ export default {
}, 500)
},
mounted() {
if (this.$refs.masonryWrapper != undefined &&
this.$refs.masonryWrapper.children[0] != undefined &&
this.$refs.masonryWrapper.children[0].children[0] != undefined &&
this.$refs.masonryWrapper.children[0].children[0].clientWidth != undefined)
this.$refs.masonryWrapper.children[0].children[0].clientWidth != undefined) {
this.itemColumnWidth = this.$refs.masonryWrapper.children[0].children[0].clientWidth;
else
this.recalculateItemsHeight();
} else
this.itemColumnWidth = 202;
},
created() {

View File

@ -134,8 +134,15 @@
<button
@click.stop.prevent="prevSlide()"
:style="{ visibility: (page > 1 && slideIndex <= 0) || slideIndex > 0 ? 'visible' : 'hidden' }"
class="slide-control-arrow arrow-left">
<span class="icon is-large">
class="slide-control-arrow arrow-left"
:aria-label="$i18n.get('previous')">
<span
v-tooltip="{
content: $i18n.get('previous'),
autoHide: true,
placement: 'auto'
}"
class="icon is-large">
<icon class="tainacan-icon tainacan-icon-48px tainacan-icon-previous"/>
</span>
</button>
@ -179,8 +186,15 @@
<button
@click.stop.prevent="nextSlide()"
:style="{ visibility: (slideIndex < slideItems.length - 1) || page < totalPages ? 'visible' : 'hidden' }"
class="slide-control-arrow arrow-right">
<span class="icon is-large has-text-turoquoise5">
class="slide-control-arrow arrow-right"
:aria-label="$i18n.get('next')">
<span
v-tooltip="{
content: $i18n.get('next'),
autoHide: true,
placement: 'auto'
}"
class="icon is-large has-text-turoquoise5">
<icon class="tainacan-icon tainacan-icon-48px tainacan-icon-next"/>
</span>
</button>
@ -198,7 +212,13 @@
:disabled="(slideIndex == slideItems.length - 1 && page == totalPages)"
class="play-button"
@click.stop.prevent="isPlaying = !isPlaying">
<span class="icon">
<span
v-tooltip="{
content: isPlaying ? $i18n.get('label_pause_slide_transition') : $i18n.get('label_begin_slide_transition'),
autoHide: true,
placement: 'auto'
}"
class="icon">
<i
:class="{ 'tainacan-icon-pausefill' : isPlaying, 'tainacan-icon-playfill' : !isPlaying }"
class="has-text-secondary tainacan-icon tainacan-icon-30px"/>
@ -248,16 +268,30 @@
<button
@click.prevent="prevGroupOfSlides()"
:style="{ visibility: (page > 1 && slideIndex <= 0) || slideIndex > 0 ? 'visible' : 'hidden' }"
class="slide-control-arrow slide-group-arrow arrow-left">
<span class="icon is-medium has-text-white">
class="slide-control-arrow slide-group-arrow arrow-left"
:aria-label="$i18n.get('label_previous_group_slides')">
<span
v-tooltip="{
content: $i18n.get('label_previous_group_slides'),
autoHide: true,
placement: 'auto'
}"
class="icon is-medium has-text-white">
<icon class="tainacan-icon tainacan-icon-20px tainacan-icon-previous"/>
</span>
</button>
<button
@click.prevent="nextGroupOfSlides()"
:style="{ visibility: (slideIndex < slideItems.length - 1) || page < totalPages ? 'visible' : 'hidden' }"
class="slide-control-arrow slide-group-arrow arrow-right">
<span class="icon is-medium has-text-white">
class="slide-control-arrow slide-group-arrow arrow-right"
:aria-label="$i18n.get('label_previous_group_slides')">
<span
v-tooltip="{
content: $i18n.get('label_previous_group_slides'),
autoHide: true,
placement: 'auto'
}"
class="icon is-medium has-text-white">
<icon class="tainacan-icon tainacan-icon-20px tainacan-icon-next"/>
</span>
</button>

View File

@ -0,0 +1,461 @@
<?php
namespace Tainacan\Tests;
/**
* @group api
*/
class TAINACAN_REST_Visibilility_Controller extends TAINACAN_UnitApiTestCase {
/*
setup initail:
create taxonomy_public
create term-a-public
create term-b-public
create taxonomy_private
create term-a-private
create term-b-private
create collection
create a metadata-public (taxonomy_public)
create a metadata-private (taxonomy_private)
create item-a
create item-b
first-test:
user not logged
get terms of taxonomy_public = 200
get terms of taxonomy_private = 401
get terms on context=edit of taxonomy_public = 401
get terms on context=edit of taxonomy_private = 401
second-test:
user logged
get terms of taxonomy_public = 200
get terms of taxonomy_private = 200
get terms on context=edit of taxonomy_public = 200
get terms on context=edit of taxonomy_private = 200
third-test:
user not logged
get taxonomies = 200 - 1 taxonomy
get taxonomies on context=edit of taxonomy_public = 401
fourth-test:
user logged
get taxonomies = 200 - 2 taxonomies
get taxonomies on context=edit = 200 - 2 taxonomies
fifth-test:
user logged
get items filter by taxonomy_public = 200
get items filter by taxonomy_private = 200
get items on context=edit filter by taxonomy_public = 200
get items on context=edit filter by taxonomy_private = 200
fifth-test:
user not logged
get items filter by taxonomy_public = 200
get items filter by taxonomy_private = 401
get items on context=edit filter by taxonomy_public = 401
get items on context=edit filter by taxonomy_private = 401
*/
public $collection;
public $taxonomy_private;
public $taxonomy_public;
public $term_public;
public $term_private;
function setUp() {
parent::setUp();
$taxonomy_public = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
'name' => 'taxonomy_public',
'description' => 'taxonomy_public',
'status' => 'publish'
),
true
);
$this->taxonomy_public = $taxonomy_public;
$term_a_public = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy_public->get_db_identifier(),
'name' => 'term_a_public'
),
true
);
$this->term_public = $term_a_public;
$term_b_public = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy_public->get_db_identifier(),
'name' => 'term_b_public'
),
true
);
$taxonomy_private = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
'name' => 'taxonomy_private',
'description' => 'taxonomy_private',
'status' => 'private'
),
true
);
$this->taxonomy_private = $taxonomy_private;
$term_a_private = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy_private->get_db_identifier(),
'name' => 'term_a_private'
),
true
);
$this->term_private = $term_a_private;
$term_b_private = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy_private->get_db_identifier(),
'name' => 'term_b_private'
),
true
);
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'collection',
'status' => 'publish'
),
true
);
$this->collection = $collection;
$metadata_tax_public = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'metadata-public',
'status' => 'publish',
'collection' => $collection,
'metadata_type' => 'Tainacan\Metadata_Types\Taxonomy',
'metadata_type_options' => [
'allow_new_terms' => true,
'taxonomy_id' => $taxonomy_public->get_id()
],
'multiple' => 'yes'
),
true
);
$metadata_tax_private = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'metadata-private',
'status' => 'private',
'collection' => $collection,
'metadata_type' => 'Tainacan\Metadata_Types\Taxonomy',
'metadata_type_options' => [
'allow_new_terms' => true,
'taxonomy_id' => $taxonomy_private->get_id()
],
'multiple' => 'yes'
),
true
);
$item_a = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item-a',
'collection' => $collection,
'status' => 'publish'
),
true
);
$item_b = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item-b',
'collection' => $collection,
'status' => 'publish'
),
true
);
wp_set_post_terms($item_a->get_id(), [$term_a_public->get_id(), $term_b_public->get_id()], $taxonomy_public->get_db_identifier());
wp_set_post_terms($item_b->get_id(), [$term_a_private->get_id(), $term_b_private->get_id()], $taxonomy_private->get_db_identifier());
}
public function test_get_terms_of_taxonomy_logged() {
//tax public
$request_public = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomy/' . $this->taxonomy_public->get_id() . '/terms'
);
$request_public->set_query_params(['hideempty' => false]);
$response = $this->server->dispatch($request_public);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(2, sizeof($data));
//tax private:
$request_private = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomy/' . $this->taxonomy_private->get_id() . '/terms'
);
$request_private->set_query_params(['hideempty' => false]);
$response = $this->server->dispatch($request_private);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(2, sizeof($data));
//tax public - context=edit:
$request_public_edit = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomy/' . $this->taxonomy_public->get_id() . '/terms'
);
$request_public_edit->set_query_params(['context' => 'edit']);
$response = $this->server->dispatch($request_public_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
// $this->assertEquals(2, sizeof($data));
//tax private - context=edit:
$request_private_edit = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomy/' . $this->taxonomy_private->get_id() . '/terms'
);
$request_public->set_query_params(['context' => 'edit']);
$response = $this->server->dispatch($request_private_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
//$this->assertEquals(2, sizeof($data));
}
public function test_get_terms_of_taxonomy_not_logged() {
wp_logout();
wp_set_current_user(0);
//tax public
$request_public = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomy/' . $this->taxonomy_public->get_id() . '/terms'
);
$request_public->set_query_params(['hideempty' => false]);
$response = $this->server->dispatch($request_public);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(2, sizeof($data));
//tax private:
$request_private = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomy/' . $this->taxonomy_private->get_id() . '/terms'
);
$request_private->set_query_params(['hideempty' => false]);
$response = $this->server->dispatch($request_private);
$status = $response->status;
$this->assertEquals(401, $status);
//tax public - context=edit:
$request_public_edit = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomy/' . $this->taxonomy_public->get_id() . '/terms'
);
$request_public_edit->set_query_params(['context' => 'edit']);
$response = $this->server->dispatch($request_public_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(401, $status);
//tax private - context=edit:
$request_private_edit = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomy/' . $this->taxonomy_private->get_id() . '/terms'
);
$request_public->set_query_params(['context' => 'edit']);
$response = $this->server->dispatch($request_private_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(401, $status);
}
public function test_get_taxonomies_logged() {
$request_public = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomies'
);
$response = $this->server->dispatch($request_public);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(2, sizeof($data));
$request_public_edit = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomies'
);
$request_public_edit->set_query_params(['context' => 'edit']);
$response = $this->server->dispatch($request_public_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(2, sizeof($data));
}
public function test_get_taxonomies_not_logged() {
wp_logout();
wp_set_current_user(0);
$request_public = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomies'
);
$response = $this->server->dispatch($request_public);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(1, sizeof($data));
$request_public_edit = new \WP_REST_Request(
'GET', $this->namespace . '/taxonomies'
);
$request_public_edit->set_query_params(['context' => 'edit']);
$response = $this->server->dispatch($request_public_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(401, $status);
}
public function test_get_items_logged() {
//tax public
$request_public = new \WP_REST_Request(
'GET', $this->namespace . '/items'
);
$tax_query = [[
'taxonomy'=> $this->taxonomy_public->get_db_identifier(),
'terms' => [$this->term_public->get_id()],
'compare' => 'IN'
]];
$request_public->set_query_params(['taxquery' => $tax_query]);
$response = $this->server->dispatch($request_public);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(1, sizeof($data));
//tax public - context=edit:
$request_public_edit = new \WP_REST_Request(
'GET', $this->namespace . '/items'
);
$request_public_edit->set_query_params(['context' => 'edit']);
$request_public_edit->set_query_params(['taxquery' => $tax_query]);
$response = $this->server->dispatch($request_public_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(1, sizeof($data));
//tax private:
$request_private = new \WP_REST_Request(
'GET', $this->namespace . '/items'
);
$tax_query = [[
'taxonomy'=> $this->taxonomy_private->get_db_identifier(),
'terms' => [$this->term_private->get_id()],
'compare' => 'IN'
]];
$request_private->set_query_params(['taxquery' => $tax_query]);
$response = $this->server->dispatch($request_private);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(1, sizeof($data));
//tax private - context=edit:
$request_private_edit = new \WP_REST_Request(
'GET', $this->namespace . '/items'
);
$request_private_edit->set_query_params(['context' => 'edit']);
$request_private_edit->set_query_params(['taxquery' => $tax_query]);
$response = $this->server->dispatch($request_private_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(1, sizeof($data));
}
public function test_get_items_not_logged() {
wp_logout();
wp_set_current_user(0);
//tax public
$request_public = new \WP_REST_Request(
'GET', $this->namespace . '/items'
);
$tax_query = [[
'taxonomy'=> $this->taxonomy_public->get_db_identifier(),
'terms' => [$this->term_public->get_id()],
'compare' => 'IN'
]];
$request_public->set_query_params(['taxquery' => $tax_query]);
$response = $this->server->dispatch($request_public);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(200, $status);
$this->assertEquals(1, sizeof($data));
//tax public - context=edit:
$request_public_edit = new \WP_REST_Request(
'GET', $this->namespace . '/items'
);
$request_public_edit->set_query_params(['taxquery' => $tax_query]);
$request_public_edit->set_query_params(['context' => 'edit']);
$response = $this->server->dispatch($request_public_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(401, $status);
//tax private:
$request_private = new \WP_REST_Request(
'GET', $this->namespace . '/items'
);
$tax_query = [[
'taxonomy'=> $this->taxonomy_private->get_db_identifier(),
'terms' => [$this->term_private->get_id()],
'compare' => 'IN'
]];
$request_private->set_query_params(['taxquery' => $tax_query]);
$response = $this->server->dispatch($request_private);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(401, $status);
//tax private - context=edit:
$request_private_edit = new \WP_REST_Request(
'GET', $this->namespace . '/items'
);
$request_private_edit->set_query_params(['context' => 'edit']);
$request_private_edit->set_query_params(['taxquery' => $tax_query]);
$response = $this->server->dispatch($request_private_edit);
$status = $response->status;
$data = $response->get_data();
$this->assertEquals(401, $status);
}
}
?>

View File

@ -62,7 +62,8 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
array(
'name' => 'genero',
'description' => 'tipos de musica',
'allow_insert' => 'yes'
'allow_insert' => 'yes',
'status' => 'publish'
),
true
);
@ -1214,7 +1215,8 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
array(
'name' => 'tax2',
'description' => 'tipos de musica',
'allow_insert' => 'yes'
'allow_insert' => 'yes',
'status' => 'publish'
),
true
);

View File

@ -35,6 +35,7 @@ class TaxonomyMetadatumTypes extends TAINACAN_UnitTestCase {
array(
'name' => 'tax_test',
'collections' => [$collection],
'status' => 'publish'
),
true
);
@ -556,6 +557,7 @@ class TaxonomyMetadatumTypes extends TAINACAN_UnitTestCase {
'taxonomy',
array(
'name' => 'tax_test',
'status' => 'publish'
),
true
);
@ -604,5 +606,51 @@ class TaxonomyMetadatumTypes extends TAINACAN_UnitTestCase {
}
function test_validate_private_taxonomy() {
$Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance();
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance();
$Tainacan_ItemMetadata = \Tainacan\Repositories\Item_Metadata::get_instance();
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test',
),
true
);
$tax = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
'name' => 'tax_test',
'status' => 'private'
),
true
);
$meta = new \Tainacan\Entities\Metadatum();
$meta->set_name('test meta');
$meta->set_status('publish');
$meta->set_metadata_type('Tainacan\Metadata_Types\Taxonomy');
$meta->set_collection($collection);
$meta->set_metadata_type_options([
'taxonomy_id' => $tax->get_id(),
'allow_new_terms' => true
]);
$this->assertFalse($meta->validate(), 'Metadatum should not validate because taxonomy is private');
$meta->set_status('private');
$this->assertTrue($meta->validate(), 'Metadatum should validate because it is private now');
}
}

666
tests/test-facets.php Normal file
View File

@ -0,0 +1,666 @@
<?php
namespace Tainacan\Tests;
/**
* Class TestCollections
*
* @package Test_Tainacan
*/
use Tainacan\Entities;
/**
* Sample test case.
*/
class Facets extends TAINACAN_UnitApiTestCase {
public $items_ids = [];
function setUp() {
parent::setUp();
$collection1 = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test_col',
'status' => 'publish'
),
true
);
$this->collection1 = $collection1;
$collection2 = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test_col',
'status' => 'publish'
),
true
);
$this->collection2 = $collection2;
$taxonomy = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
'name' => 'genero',
'description' => 'tipos de musica',
'allow_insert' => 'yes',
'status' => 'publish'
),
true
);
$this->taxonomy = $taxonomy;
$term_1 = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy->get_db_identifier(),
'name' => 'Term for collection 1'
),
true
);
$term_2 = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy->get_db_identifier(),
'name' => 'Term for collection 2'
),
true
);
$term_all = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy->get_db_identifier(),
'name' => 'Term for all'
),
true
);
$term_1_c = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy->get_db_identifier(),
'name' => 'Term for collection 1 child',
'parent' => $term_1->get_id()
),
true
);
$term_2_c = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy->get_db_identifier(),
'name' => 'Term for collection 2 child',
'parent' => $term_2->get_id()
),
true
);
$term_all_c = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy->get_db_identifier(),
'name' => 'Term for all child',
'parent' => $term_all->get_id()
),
true
);
$term_nobody = $this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $taxonomy->get_db_identifier(),
'name' => 'Term for nobody',
),
true
);
$meta_1_tax = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'category1',
'status' => 'publish',
'collection' => $collection1,
'metadata_type' => 'Tainacan\Metadata_Types\Taxonomy',
'metadata_type_options' => [
'allow_new_terms' => true,
'taxonomy_id' => $taxonomy->get_id()
],
'multiple' => 'yes'
),
true
);
$this->meta_1_tax = $meta_1_tax;
$meta_2_tax = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'category2',
'status' => 'publish',
'collection' => $collection2,
'metadata_type' => 'Tainacan\Metadata_Types\Taxonomy',
'metadata_type_options' => [
'allow_new_terms' => true,
'taxonomy_id' => $taxonomy->get_id()
],
'multiple' => 'yes'
),
true
);
$this->meta_2_tax = $meta_2_tax;
$metadatum_text = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'text',
'status' => 'publish',
'collection' => $collection1,
'metadata_type' => 'Tainacan\Metadata_Types\Text',
),
true
);
$this->metadatum_text = $metadatum_text;
$metadatum_repo = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'repo',
'status' => 'publish',
'collection_id' => 'default',
'metadata_type' => 'Tainacan\Metadata_Types\Text',
),
true
);
$this->metadatum_repo = $metadatum_repo;
$meta_relationship = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'relationship',
'status' => 'publish',
'collection' => $collection2,
'metadata_type' => 'Tainacan\Metadata_Types\Relationship',
'metadata_type_options' => [
'allow_new_terms' => true,
'collection_id' => $collection1->get_id(),
'search' => []
]
),
true
);
$this->meta_relationship = $meta_relationship;
for ($i = 1; $i<=80; $i++) {
$title = 'testeItem ' . str_pad($i, 2, "0", STR_PAD_LEFT);
$col = $i <= 40 ? $collection1 : $collection2;
$item = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => $title,
'collection' => $col,
'status' => 'publish'
),
true
);
$this->items_ids[] = $item->get_id();
$this->tainacan_item_metadata_factory->create_item_metadata($item, $metadatum_repo, 'Value ' . $i);
if ($i <= 40) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $metadatum_text, $i % 2 == 0 ? 'even' : 'odd');
} else {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_relationship, $this->items_ids[$i - 41]);
}
if ($i <= 10) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_1_tax, [$term_1->get_id()]);
} elseif($i <= 20) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_1_tax, [$term_1_c->get_id()]);
} elseif($i <= 30) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_1_tax, [$term_all->get_id()]);
} elseif($i <= 40) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_1_tax, [$term_all_c->get_id()]);
} elseif($i <= 50) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_2_tax, [$term_all->get_id()]);
} elseif($i <= 60) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_2_tax, [$term_all_c->get_id()]);
} elseif($i <= 70) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_2_tax, [$term_2->get_id()]);
} elseif($i <= 80) {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_2_tax, [$term_2_c->get_id()]);
}
}
$this->repository = \Tainacan\Repositories\Metadata::get_instance();
}
// function test_setup() {
// $this->assertEquals(80, sizeof($this->items_ids));
// }
/**
* get the values from the method response (useful for refactoring)
*/
private function get_values($response) {
return $response['values'];
}
function test_defaults_values() {
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id() );
//$items = \Tainacan\Repositories\Items::get_instance()->fetch( [], null );
// var_dump($items->request);
// var_dump($items->found_posts);
//var_dump($values);
//
// $metas = ($items[0]->get_metadata());
//
// foreach($metas as $m) {
// var_dump( $m->get_metadatum()->get_id() );
// var_dump( $m->get_metadatum()->get_name() );
// var_dump( $m->get_value() );
// }
//
// $metas = ($items[39]->get_metadata());
//
// foreach($metas as $m) {
// var_dump( $m->get_metadatum()->get_id() );
// var_dump( $m->get_metadatum()->get_name() );
// var_dump( $m->get_value() );
// }
//
// var_dump($this->metadatum_repo->get_id());
//
$values = $this->get_values($values);
$this->assertEquals( 80, sizeof($values) );
// test defaults with filter
$values = $this->repository->fetch_all_metadatum_values( $this->meta_1_tax->get_id(), [
'items_filter' => [
'meta_query' => [
[
'key' => $this->metadatum_repo->get_id(),
'value' => ['Value 1', 'Value 10', 'Value 20', 'Value 30', 'Value 40', 'Value 50', 'Value 60', 'Value 70', 'Value 80']
]
]
]
]);
$values = $this->get_values($values);
$this->assertEquals( 3, sizeof($values) );
// test defaults 1 collection with filter
$values = $this->repository->fetch_all_metadatum_values( $this->meta_1_tax->get_id(), [
'collection_id' => $this->collection1->get_id(),
'items_filter' => [
'meta_query' => [
[
'key' => $this->metadatum_repo->get_id(),
'value' => ['Value 1', 'Value 10', 'Value 20', 'Value 30', 'Value 40', 'Value 50', 'Value 60', 'Value 70', 'Value 80']
]
]
]
]);
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
// test defaults 1 collection
$values = $this->repository->fetch_all_metadatum_values( $this->meta_1_tax->get_id(), [
'collection_id' => $this->collection1->get_id()
]);
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
// test default text metadata
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_text->get_id());
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
// test default relationship
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id());
$values = $this->get_values($values);
$this->assertEquals( 40, sizeof($values) );
// test default metadatum repo
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id());
$values = $this->get_values($values);
$this->assertEquals( 80, sizeof($values) );
// test defaults 1 collection with filter
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id(), [
'collection_id' => $this->collection1->get_id(),
'items_filter' => [
'meta_query' => [
[
'key' => $this->metadatum_text->get_id(),
'value' => 'odd'
]
]
]
] );
$values = $this->get_values($values);
$this->assertEquals( 20, sizeof($values) );
// test default text metadata with filter
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_text->get_id(), [
'count_items' => true,
'items_filter' => [
'meta_query' => [
[
'key' => $this->metadatum_repo->get_id(),
'value' => ['Value 2', 'Value 4', 'Value 6', 'Value 8', 'Value 1', 'Value 3', 'Value 80', 'Value 78', 'Value 79']
]
]
]
] );
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
$this->assertEquals( 4, $values[0]['total_items']);
$this->assertEquals( 2, $values[1]['total_items']);
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_text->get_id(), [
'count_items' => true,
'items_filter' => [
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => 'Term for collection 1'
]
]
]
] );
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
$this->assertEquals(10, $values[0]['total_items']);
$this->assertEquals(10, $values[1]['total_items']);
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_text->get_id(), [
'count_items' => true,
'items_filter' => [
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => 'Term for collection 1 child'
]
]
]
] );
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
$this->assertEquals(5, $values[0]['total_items']);
$this->assertEquals(5, $values[1]['total_items']);
// test default taxonomy with filter
$values = $this->repository->fetch_all_metadatum_values( $this->meta_2_tax->get_id(),[
//'collection_id' => $this->collection2->get_id(),
'items_filter' => [
'meta_query' => [
[
'key' => $this->meta_relationship->get_id(),
'value' => [$this->items_ids[1], $this->items_ids[10], $this->items_ids[20], $this->items_ids[30], $this->items_ids[40]]
]
]
]
]);
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
// test default relationship with filter
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
//'collection_id' => $this->collection2->get_id(),
'items_filter' => [
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => ['Term for collection 2','Term for collection 2 child', 'Term for all child']
]
]
]
]);
$values = $this->get_values($values);
$this->assertEquals( 30, sizeof($values) );
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
//'collection_id' => $this->collection2->get_id(),
'items_filter' => [
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => ['Term for collection 2','Term for collection 2 child', 'Term for all child']
]
],
'meta_query' => [
[
'key' => $this->metadatum_repo->get_id(),
'value' => ['Value 80', 'Value 75', 'Value 70', 'Value 65', 'Value 60','Value 55','Value 50','Value 45','Value 40']
]
]
]
]);
$values = $this->get_values($values);
$this->assertEquals( 6, sizeof($values) );
// test defaults 1 collection without filter
// test default text metadata without filter
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_text->get_id(), [
'collection_id' => $this->collection1->get_id(),
'items_filter' => false
] );
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
// test default relationship without filter
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
'collection_id' => $this->collection2->get_id(),
'items_filter' => false
] );
$values = $this->get_values($values);
$this->assertEquals( 40, sizeof($values) );
// test search
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id(), [
'search' => '23'
] );
$values = $this->get_values($values);
$this->assertEquals( 1, sizeof($values) );
$this->assertEquals( 'Value 23', $values[0]['value']);
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id(), [
'search' => '2'
] );
$values = $this->get_values($values);
$this->assertEquals( 17, sizeof($values) ); // 2, 12, 20, 21, 22, 23 ... 32, 42...
// test search relationship
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
'collection_id' => $this->collection2->get_id(),
'search' => '23'
] );
$values = $this->get_values($values);
$this->assertEquals( 1, sizeof($values) );
$this->assertEquals( 'testeItem 23', $values[0]['label']);
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
'collection_id' => $this->collection2->get_id(),
'search' => '66'
] );
$values = $this->get_values($values);
$this->assertEquals( 0, sizeof($values) );
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
'collection_id' => $this->collection2->get_id(),
'search' => '2'
] );
$values = $this->get_values($values);
$this->assertEquals( 13, sizeof($values) ); // 2, 12, 20, 21, 22, 23 ... 32
// test search with filter
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id(), [
'search' => '2',
'items_filter' => [
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => ['Term for all child', 'Term for collection 1 child', 'Term for collection 2 child']
]
]
]
] );
$values = $this->get_values($values);
$this->assertEquals( 5, sizeof($values) ); // 12, 20, 32, 52, 72
$valuesParsed = array_map(function($el) {
return $el['label'];
}, $values);
$this->assertContains( 'Value 12', $valuesParsed);
$this->assertContains( 'Value 20', $valuesParsed);
$this->assertContains( 'Value 32', $valuesParsed);
$this->assertContains( 'Value 52', $valuesParsed);
$this->assertContains( 'Value 72', $valuesParsed);
// test search relationship with filter
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
'search' => '2',
'items_filter' => [
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => ['Term for all child', 'Term for collection 2 child']
]
]
]
] );
$values = $this->get_values($values);
// items in the range of 51-60 and 71-80 have the queried terms and are related to items in the firts collection with the number -40
$this->assertEquals( 3, sizeof($values) ); // 12, 20, 32
$valuesParsed = array_map(function($el) {
return $el['label'];
}, $values);
$this->assertContains( 'testeItem 12', $valuesParsed);
$this->assertContains( 'testeItem 20', $valuesParsed);
$this->assertContains( 'testeItem 32', $valuesParsed);
// test search without filter
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
'search' => '2',
'items_filter' => false
] );
$values = $this->get_values($values);
$this->assertEquals( 13, sizeof($values) ); // 2,12,20-29,32
$values = $this->repository->fetch_all_metadatum_values( $this->meta_2_tax->get_id(), [
'count_items' => true,
'search' => 'collection',
'items_filter' => false
] );
$values = $this->get_values($values);
$this->assertEquals( 2, sizeof($values) );
$valuesParsed = array_map(function($el) {
$this->assertEquals( 20, $el['total_items'] );
return $el['label'];
}, $values);
$this->assertContains( 'Term for collection 1', $valuesParsed);
$this->assertContains( 'Term for collection 2', $valuesParsed);
// test search relationship without filter
$values = $this->repository->fetch_all_metadatum_values( $this->meta_relationship->get_id(), [
'search' => 'testeItem 1',
'items_filter' => false
] );
$values = $this->get_values($values);
$this->assertEquals( 10, sizeof($values) );
// test offset normal
$values_p1 = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id(), [
'number' => 10,
'offset' => 0,
'items_filter' => false
] );
$values_p1 = $this->get_values($values_p1);
$values_p2 = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id(), [
'number' => 10,
'offset' => 10,
'items_filter' => false
] );
$values_p2 = $this->get_values($values_p2);
$values_p3 = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id(), [
'number' => 10,
'offset' => 20,
'items_filter' => false
] );
$values_p3 = $this->get_values($values_p3);
$this->assertEquals($values_p1[9]['label'], 'Value 18');
$this->assertEquals($values_p2[9]['label'], 'Value 27');
$this->assertEquals($values_p3[9]['label'], 'Value 36');
// test include normal
$values = $this->repository->fetch_all_metadatum_values( $this->metadatum_repo->get_id(), [
'include' => ['Value 1','Value 2','Value 55','Value 77'],
'number' => 10,
'offset' => 0,
'items_filter' => [
'meta_query' => [
[
'key' => $this->metadatum_text->get_id(),
'value' => ['even']
]
]
]
] );
$values = $this->get_values($values);
$valuesParsed = array_map(function($el) {
return $el['label'];
}, $values);
$this->assertContains( 'Value 1', $valuesParsed);
$this->assertContains( 'Value 2', $valuesParsed);
$this->assertContains( 'Value 55', $valuesParsed);
$this->assertContains( 'Value 77', $valuesParsed);
// test count items normal
// test default taxonomy
// test default taxonomy without filter
// test search taxonomy
// test search taxonomy with filter
// test search taxonomy without filter
// test offset taxonomy
// test include taxonomy
// test count items taxonomy
//
}
}

View File

@ -334,6 +334,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
'taxonomy',
array(
'name' => 'genero',
'status' => 'publish'
),
true
);

View File

@ -304,4 +304,93 @@ class Item_Metadata extends TAINACAN_UnitTestCase {
$this->assertEquals($item_metadata_text->get_value_as_html(), $response_text);
$this->assertEquals($item_metadata_textarea->get_value_as_html(), $response_textarea);
}
/**
* @group test_item_metadata_has_value
*/
function test_item_metadata_has_value() {
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste'
),
true
);
$i = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item teste',
'description' => 'description',
'collection' => $collection,
'status' => 'publish'
),
true
);
$metadatum_textarea = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'metadadoTextarea',
'description' => 'descricao',
'collection_id' => $collection->get_id(),
'metadata_type' => 'Tainacan\Metadata_Types\Textarea',
),
true
);
$value_textarea = '';
$item_metadata_textarea = new \Tainacan\Entities\Item_Metadata_Entity($i, $metadatum_textarea);
$item_metadata_textarea->set_value($value_textarea);
$item_metadata_textarea->validate();
$item_metadata_textarea = $Tainacan_Item_Metadata->insert($item_metadata_textarea);
$this->assertFalse($item_metadata_textarea->has_value());
$item_metadata_textarea->set_value('has_value');
$item_metadata_textarea->validate();
$item_metadata_textarea = $Tainacan_Item_Metadata->insert($item_metadata_textarea);
$this->assertTrue($item_metadata_textarea->has_value());
$metadatum_text = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'metadadoText',
'description' => 'descricao',
'collection_id' => $collection->get_id(),
'metadata_type' => 'Tainacan\Metadata_Types\Text',
'multiple' => 'yes'
),
true
);
$item_metadata_text = new \Tainacan\Entities\Item_Metadata_Entity($i, $metadatum_text);
$item_metadata_text->set_value([
''
]);
$item_metadata_text->validate();
$item_metadata = $Tainacan_Item_Metadata->insert($item_metadata_text);
$this->assertFalse($item_metadata->has_value());
$item_metadata_text->set_value([
''
]);
$item_metadata_text->validate();
$item_metadata_text = $Tainacan_Item_Metadata->insert($item_metadata_text);
$item_metadata_text->set_value([
'has_value'
]);
$this->assertTrue($item_metadata_text->has_value());
}
}