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

This commit is contained in:
vnmedeiros 2019-10-03 16:58:54 -03:00
commit 3a09a83aed
51 changed files with 2349 additions and 1770 deletions

View File

@ -70,19 +70,19 @@
class="table-creation column-small-width"
@click="openActivityDetailsModal(activity)"
:label="$i18n.get('label_activity_date')"
:aria-label="$i18n.get('label_activity_date') + ': ' + activity.log_date">
:aria-label="$i18n.get('label_activity_date') + ': ' + activity.date">
<p
v-tooltip="{
delay: {
show: 500,
hide: 300,
},
content: activity.log_date,
content: activity.date,
autoHide: false,
classes: ['tooltip', 'repository-tooltip'],
placement: 'auto-start'
}"
v-html="activity.log_date"/>
v-html="activity.date"/>
</td>
<!-- Approbation -->
<!--<td-->
@ -127,7 +127,7 @@
<script>
import { mapActions } from 'vuex';
import ActivityDetailsModal from '../other/activity/activity-details-modal.vue';
import ActivityDetailsModal from '../other/activity-details-modal.vue';
import ThreeStateToggleButton from '../other/three-state-toggle-button.vue';
export default {
@ -172,7 +172,7 @@
parent: this,
component: ActivityDetailsModal,
props: {
activity: activity,
activityId: activity.id,
},
events: {
approveActivity: (activityId) => this.approveActivity(activityId),

View File

@ -117,7 +117,7 @@
@input="onChangeEnable($event, index)"/>
<a
:style="{ visibility: filter.collection_id != collectionId && !isRepositoryLevel? 'hidden' : 'visible' }"
@click.prevent="editFilter(filter)">
@click.prevent="toggleFilterEdition(filter.id)">
<span
v-tooltip="{
content: $i18n.get('edit'),
@ -353,6 +353,18 @@ export default {
components: {
FilterEditionForm
},
watch: {
'$route.query': {
handler(newQuery) {
if (newQuery.edit != undefined) {
let existingFilterIndex = this.activeFilterList.findIndex((filter) => filter.id == newQuery.edit);
if (existingFilterIndex >= 0)
this.editFilter(this.activeFilterList[existingFilterIndex])
}
},
immediate: true
}
},
beforeRouteLeave ( to, from, next ) {
let hasUnsavedForms = false;
for (let editForm in this.editForms) {
@ -524,7 +536,7 @@ export default {
this.selectedFilterType = {}
this.allowedFilterTypes = [];
this.editFilter(filter);
this.toggleFilterEdition(filter.id);
})
.catch((error) => {
this.$console.error(error);
@ -559,22 +571,18 @@ export default {
// this.deleteTemporaryFilter(this.newFilterIndex);
this.newFilterIndex = 0;
},
editFilter(filter) {
toggleFilterEdition(filterId) {
// Closing collapse
if (this.openedFilterId == filter.id) {
if (this.openedFilterId == filterId) {
this.openedFilterId = '';
this.$router.push({ query: {}});
// Opening collapse
} else {
if (this.openedFilterId == '' && this.choosenMetadatum.id != undefined) {
this.availableMetadata.push(this.choosenMetadatum);
this.choosenMetadatum = {};
this.allowedFilterTypes = [];
this.selectedFilterType = {};
// this.deleteTemporaryFilter(this.newFilterIndex);
this.newFilterIndex = 0;
this.$router.push({ query: { edit: filterId}})
}
},
editFilter(filter) {
this.openedFilterId = filter.id;
// First time opening
@ -588,17 +596,18 @@ export default {
this.editForms[this.openedFilterId].saved = false;
}
}
}
},
onEditionFinished() {
this.formWithErrors = '';
delete this.editForms[this.openedFilterId];
this.openedFilterId = '';
this.$router.push({ query: {}});
},
onEditionCanceled() {
this.formWithErrors = '';
delete this.editForms[this.openedFilterId];
this.openedFilterId = '';
this.$router.push({ query: {}});
},
getProperPreviewMinHeight() {
for (let filterType of this.allowedFilterTypes) {
@ -610,6 +619,55 @@ export default {
}
}
return 190;
},
refreshFilters() {
this.fetchFilters({
collectionId: this.collectionId,
isRepositoryLevel: this.isRepositoryLevel,
isContextEdit: !this.isOnTheme,
includeDisabled: true,
}).then((resp) => {
resp.request
.then(() => {
this.isLoadingMetadatumTypes = true;
// Checks URL as router watcher would not wait for list to load
if (this.$route.query.edit != undefined) {
let existingFilterIndex = this.activeFilterList.findIndex((filter) => filter.id == this.$route.query.edit);
if (existingFilterIndex >= 0)
this.editFilter(this.activeFilterList[existingFilterIndex]);
}
// Cancels previous Request
if (this.metadataSearchCancel != undefined)
this.metadataSearchCancel.cancel('Metadata search Canceled.');
// Needs to be done after activeFilterList exists to compare and remove chosen metadata.
this.fetchMetadata({
collectionId: this.collectionId,
isRepositoryLevel: this.isRepositoryLevel,
isContextEdit: true
}).then((resp) => {
resp.request
.then(() => {
this.isLoadingMetadatumTypes = false;
this.updateListOfMetadata();
})
.catch(() => {
this.isLoadingMetadatumTypes = false;
});
// Search Request Token for cancelling
this.metadataSearchCancel = resp.source;
})
.catch(() => this.isLoadingMetadatumTypes = false);
})
.catch(() => this.isLoadingFilters = false);
// Search Request Token for cancelling
this.filtersSearchCancel = resp.source;
})
.catch(() => this.isLoadingFilters = false);
}
},
mounted() {
@ -643,46 +701,8 @@ export default {
if (this.filtersSearchCancel != undefined)
this.filtersSearchCancel.cancel('Filters search Canceled.');
this.fetchFilters({
collectionId: this.collectionId,
isRepositoryLevel: this.isRepositoryLevel,
isContextEdit: !this.isOnTheme,
includeDisabled: true,
}).then((resp) => {
resp.request
.then(() => {
this.isLoadingMetadatumTypes = true;
// Cancels previous Request
if (this.metadataSearchCancel != undefined)
this.metadataSearchCancel.cancel('Metadata search Canceled.');
// Needs to be done after activeFilterList exists to compare and remove chosen metadata.
this.fetchMetadata({
collectionId: this.collectionId,
isRepositoryLevel: this.isRepositoryLevel,
isContextEdit: true
}).then((resp) => {
resp.request
.then(() => {
this.isLoadingMetadatumTypes = false;
this.updateListOfMetadata();
})
.catch(() => {
this.isLoadingMetadatumTypes = false;
});
// Search Request Token for cancelling
this.metadataSearchCancel = resp.source;
})
.catch(() => this.isLoadingMetadatumTypes = false);
})
.catch(() => this.isLoadingFilters = false);
// Search Request Token for cancelling
this.filtersSearchCancel = resp.source;
})
.catch(() => this.isLoadingFilters = false);
// Loads Filters
this.refreshFilters();
// Obtains collection name
if (!this.isRepositoryLevel) {

View File

@ -594,7 +594,14 @@ export default {
},
addNewMetadatum(newMetadatum, newIndex) {
this.sendMetadatum({collectionId: this.collectionId, name: newMetadatum.name, metadatumType: newMetadatum.className, status: 'auto-draft', isRepositoryLevel: this.isRepositoryLevel, newIndex: newIndex})
this.sendMetadatum({
collectionId: this.collectionId,
name: newMetadatum.name,
metadatumType: newMetadatum.className,
status: 'auto-draft',
isRepositoryLevel: this.isRepositoryLevel,
newIndex: newIndex
})
.then((metadatum) => {
if (!this.isRepositoryLevel)

View File

@ -0,0 +1,780 @@
<template>
<div class="tainacan-modal-content">
<header
v-if="!isLoadingActivity"
class="tainacan-modal-title">
<h2>{{ activity.title ? activity.title : $i18n.get('activity') }}</h2>
<hr>
<p>{{ activityCreationDate + ', ' + $i18n.get('info_by_inner') }} <strong> {{ activity.user_name }}</strong></p>
</header>
<b-loading
:is-full-page="false"
:active.sync="isLoadingActivity"
:can-cancel="false"/>
<div
v-if="!isLoadingActivity"
class="modal-card-body">
<div class="content">
<p v-if="activity.description"><strong>{{ $i18n.get('label_activity_description') }}:</strong> {{ activity.description }}</p>
<p v-if="activity.object">
<strong>{{ $i18n.get('label_related_to') }}: </strong>
<span v-html="relatedToLink" />
</p>
</div>
<!-- LEGACY LOG API RETURN -->
<div v-if="activity.legacy != undefined && activity.legacy == true">
<template v-for="(diff, attributeName, index) in activity.log_diffs">
<div
:key="index"
class="columns">
<!-- OLD -->
<div class="column is-6">
<!-- Thumbnail -->
<div
class="content"
v-if="attributeName == 'thumbnail'">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<div>
<picture>
<img
width="150px"
:src="diff.old ? diff.old : placeholderSquareImage"
:alt="attributeName">
</picture>
</div>
</div>
<div
v-if="attributeName == 'attachments'"
class="content">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<div
class="tainacan-attachments-in-modal"
v-if="diff.old.length">
<template v-for="(attachment, anotherIndex) in diff.old">
<file-item
:key="anotherIndex"
:modal-on-click="false"
:show-name="true"
:file="{
title: { rendered: attachment.title },
guid: { rendered: attachment.url },
mime_type: attachment.mime_type,
media_type: attachment.mime_type.includes('image') ? 'image' : 'other'
}"/>
</template>
</div>
<div v-else>
<p>{{ infoEmpty }}</p>
</div>
</div>
<div
class="content"
v-if="!['thumbnail', 'attachments'].includes(attributeName)">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName.replace(/_/g, ' ') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<!-- Is array with length 1 -->
<p
class="tainacan-p-break"
v-if="(diff.old instanceof Array) &&
(diff.old.length == 1) &&
!(diff.old[0] instanceof Object)">
{{ diff.old.toString() }}
</p>
<div
v-else-if="attributeName == 'metadata_order'"
class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in diff.old"
:key="diffTitle">
{{ diff.old ? `ID: ${diffContent.id} | Enabled: ${diffContent.enabled}` : infoEmpty }}
</p>
</div>
<div
v-else-if="attributeName == 'filters_order'"
class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in diff.old"
:key="diffTitle">
{{ diff.old ? `ID: ${diffContent.id} | Enabled: ${diffContent.enabled}` : infoEmpty }}
</p>
</div>
<div
v-else-if="attributeName == 'metadata_type_options'"
class="content">
<p class="tainacan-p-break">
{{ diff.old ?
`Taxonomy ID: ${diff.old.taxonomy_id};
Input type: ${diff.old.input_type};
Allow new terms: ${diff.old.allow_new_terms}` : infoEmpty }}
</p>
</div>
<!-- -->
<p
class="tainacan-p-break"
v-else>
{{ diff.old ? (diff.old instanceof Array && !diff.old.length) ? infoEmpty : diff.old.toString().replace(/,/g, ' ') : infoEmpty }}
</p>
</div>
</div>
<!-- NEW -->
<div class="column is-6">
<!-- Thumbnail -->
<div
class="content"
v-if="attributeName == 'thumbnail'">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<div>
<picture>
<img
width="150px"
:src="diff.new ? diff.new : placeholderSquareImage"
:alt="attributeName">
</picture>
</div>
</div>
<div
v-if="attributeName == 'attachments'"
class="content">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<div
class="tainacan-attachments-in-modal"
v-if="diff.new.length">
<template v-for="(attachment, index) in diff.new">
<file-item
:key="index"
:modal-on-click="false"
:show-name="true"
:file="{
title: { rendered: attachment.title },
guid: { rendered: attachment.url },
mime_type: attachment.mime_type,
media_type: attachment.mime_type.includes('image') ? 'image' : 'other'
}"/>
</template>
</div>
<div v-else>
<p>{{ infoEmpty }}</p>
</div>
</div>
<div
class="content"
v-if="!['thumbnail', 'attachments'].includes(attributeName)">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName.replace(/_/g, ' ') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<!-- Is array with length 1 -->
<p
class="tainacan-p-break"
v-if="(diff.new instanceof Array) &&
(diff.new.length == 1) &&
!(diff.new[0] instanceof Object)">
{{ diff.new.toString() }}
</p>
<div
v-else-if="attributeName == 'metadata_order'"
class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in diff.new"
:key="diffTitle">
{{ `ID: ${diffContent.id} | Enabled: ${diffContent.enabled}` }}
</p>
</div>
<div
v-else-if="attributeName == 'filters_order'"
class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in diff.new"
:key="diffTitle">
{{ `ID: ${diffContent.id} | Enabled: ${diffContent.enabled}` }}
</p>
</div>
<div
v-else-if="attributeName == 'metadata_type_options'"
class="content">
<p class="tainacan-p-break">
{{ `Taxonomy ID: ${diff.new.taxonomy_id};
Input type: ${diff.new.input_type};
Allow new terms: ${diff.new.allow_new_terms}` }}
</p>
</div>
<!-- -->
<p
class="tainacan-p-break"
v-else>
{{ diff.new ? (diff.new instanceof Array && !diff.new.length) ? infoEmpty : diff.new.toString().replace(/,/g, ' ') : infoEmpty }}
</p>
</div>
</div>
</div>
</template>
</div>
<!-- NEW LOG API RETURN -->
<div v-else>
<div class="columns">
<!-- OLD -->
<div class="column is-6">
<div
v-if="activity.action == 'update-thumbnail'"
class="content">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ $i18n.get('label_thumbnail') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<p
v-if="activity.old_value && activity.old_value.thumb && activity.old_value.thumb[0]"
class="tainacan-p-break">
<img
style="margin: 12px 0; max-width: 150px;"
:alt="$i18n.get('label_thumbnail')"
:src="activity.old_value.thumb[0]" >
</p>
<p v-else>{{ infoEmpty }}</p>
</div>
<div
v-if="activity.action == 'new-attachment'"
class="content">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ $i18n.get('label_attachment') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<div v-if="activity.old_value.url">
<file-item
:modal-on-click="false"
:show-name="true"
:file="{
title: { rendered: activity.old_value.title },
guid: { rendered: activity.old_value.url },
mime_type: activity.old_value.mime_type,
media_type: activity.old_value.mime_type.includes('image') ? 'image' : 'other'
}"/>
</div>
<div v-else>
<p>{{ infoEmpty }}</p>
</div>
</div>
<div
v-if="activity.action == 'update-document'"
class="content">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ $i18n.get('label_document') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<div
:key="index"
v-for="(attributeValue, attributeName, index) of activity.old_value">
<p
v-if="attributeName == 'thumb' && attributeValue[0]"
class="tainacan-p-break">
<img
style="margin: 12px 0; max-width: 150px;"
:alt="$i18n.get('label_document')"
:src="attributeValue[0]" >
</p>
<p
v-else
v-html="`<strong>` + attributeName + `: </strong>` + (attributeValue ? attributeValue : infoEmpty)"
class="tainacan-p-break" />
</div>
</div>
<div
class="content"
v-if="activity.action == 'update-metadata-order' || activity.action == 'update-filters-order'">
<div
:key="index"
v-for="(attributeValue, attributeName, index) in activity.old_value">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<div class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in attributeValue"
:key="diffTitle"
v-html="attributeValue ? `ID: ${diffContent.id} <span class='is-italic'>(${diffContent.enabled ? $i18n.get('label_enabled') : $i18n.get('label_disabled')})</span>` : infoEmpty " />
</div>
</div>
</div>
<div
class="content"
v-if="activity.action == 'update'">
<div
:key="index"
v-for="(attributeValue, attributeName, index) in activity.old_value">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<!-- Is array with length 1 -->
<p
class="tainacan-p-break"
v-if="(attributeValue instanceof Array) &&
(attributeValue.length == 1) &&
!(attributeValue[0] instanceof Object)">
{{ attributeValue.toString() }}
</p>
<div
v-else-if="attributeName == 'metadata_type_options'"
class="content">
<p
:key="innerIndex"
v-for="(innerValue, innerName, innerIndex) of attributeValue"
class="tainacan-p-break">
<strong>{{ innerName + ': ' }}</strong>{{ innerValue ? innerValue : infoEmpty }}
<br>
</p>
</div>
<p
class="tainacan-p-break"
v-else
v-html="(!attributeValue || (attributeValue instanceof Array && !attributeValue.length)) ? infoEmpty : (attributeValue instanceof Array ? attributeValue.join(`<span class='multivalue-separator'>|</span>`) : attributeValue)" />
</div>
</div>
<div
class="content"
v-if="activity.action == 'update-metadata-value'">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ activity.metadata && activity.metadata.name ? activity.metadata.name : $i18n.get('metadatum') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<p
class="tainacan-p-break"
v-html="!activity.old_value ? infoEmpty : (activity.old_value instanceof Array ? activity.old_value.join(`<span class='multivalue-separator'>|</span>`) : activity.old_value)" />
</div>
</div>
<!-- NEW -->
<div class="column is-6">
<div
v-if="activity.action == 'update-thumbnail'"
class="content">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ $i18n.get('label_thumbnail') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<p
v-if="activity.new_value && activity.new_value.thumb && activity.new_value.thumb[0]"
class="tainacan-p-break">
<img
style="margin: 12px 0; max-width: 150px;"
:alt="$i18n.get('label_thumbnail')"
:src="activity.new_value.thumb[0]" >
</p>
<p v-else>{{ infoEmpty }}</p>
</div>
<div
v-if="activity.action == 'new-attachment'"
class="content">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ $i18n.get('label_attachment') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<div v-if="activity.new_value.url">
<file-item
:modal-on-click="false"
:show-name="true"
:file="{
title: { rendered: activity.new_value.title },
guid: { rendered: activity.new_value.url },
mime_type: activity.new_value.mime_type,
media_type: activity.new_value.mime_type.includes('image') ? 'image' : 'other'
}"/>
</div>
<div v-else>
<p>{{ infoEmpty }}</p>
</div>
</div>
<div
v-if="activity.action == 'update-document'"
class="content">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ $i18n.get('label_document') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<div
:key="index"
v-for="(attributeValue, attributeName, index) of activity.new_value">
<p
v-if="attributeName == 'thumb' && attributeValue[0]"
class="tainacan-p-break">
<img
style="margin: 12px 0; max-width: 150px;"
:alt="$i18n.get('label_document')"
:src="attributeValue[0]" >
</p>
<p
v-else
v-html="`<strong>` + attributeName + `: </strong>` + (attributeValue ? attributeValue : infoEmpty)"
class="tainacan-p-break" />
</div>
</div>
<div
class="content"
v-if="activity.action == 'update-metadata-order' || activity.action == 'update-filters-order'">
<div
:key="index"
v-for="(attributeValue, attributeName, index) in activity.new_value">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<div class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in attributeValue"
:key="diffTitle"
v-html="attributeValue ? `ID: ${diffContent.id} <span class='is-italic'>(${diffContent.enabled ? $i18n.get('label_enabled') : $i18n.get('label_disabled')})</span>` : infoEmpty " />
</div>
</div>
</div>
<div
:key="index"
v-for="(attributeValue, attributeName, index) in activity.new_value">
<div
class="content"
v-if="activity.action == 'update'">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ attributeName }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<div
v-if="attributeName == 'metadata_type_options'"
class="content">
<p
:key="innerIndex"
v-for="(innerValue, innerName, innerIndex) of attributeValue"
class="tainacan-p-break">
<strong>{{ innerName + ': ' }}</strong>{{ innerValue ? innerValue : infoEmpty }}
<br>
</p>
</div>
<div
v-else-if="attributeName == 'header_image_id'"
class="content">
<p class="tainacan-p-break">
{{ attributeValue ? attributeValue : infoEmpty }}
<br>
<img
style="margin: 12px 0; max-width: 160px;"
v-if="activity.terms && activity.terms.header_image"
:alt="$i18n.get('label_header_image')"
:src="activity.terms.header_image" >
</p>
</div>
<p
class="tainacan-p-break"
v-else
v-html="(!attributeValue || (attributeValue instanceof Array && !attributeValue.length)) ? infoEmpty : (attributeValue instanceof Array ? attributeValue.join(`<span class='multivalue-separator'>|</span>`) : attributeValue)" />
</div>
</div>
<div
class="content"
v-if="activity.action == 'update-metadata-value'">
<p class="is-capitalized has-text-blue5 has-text-weight-bold">
{{ activity.metadata && activity.metadata.name ? activity.metadata.name : $i18n.get('metadatum') }}
<small class="has-text-gray4 has-text-weight-normal"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<p
class="tainacan-p-break"
v-html="!activity.new_value ? infoEmpty : (activity.new_value instanceof Array ? activity.new_value.join(`<span class='multivalue-separator'>|</span>`) : activity.new_value)" />
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="control">
<button
class="button is-outlined"
type="button"
@click="$parent.close()">
{{ $i18n.get('close') }}
</button>
<div class="buttons is-pulled-right">
<!--<button-->
<!--v-if="activity.status != 'publish'"-->
<!--@click="notApproveActivity"-->
<!--type="button"-->
<!--class="button is-danger">-->
<!--<b-icon-->
<!--size="is-small"-->
<!--icon="close"/>-->
<!--<span>{{ $i18n.get('not_approve_item') }}</span>-->
<!--</button>-->
<!--<button-->
<!--v-if="activity.status != 'publish'"-->
<!--@click="approveActivity"-->
<!--type="button"-->
<!--class="button is-secondary">-->
<!--<b-icon-->
<!--size="is-small"-->
<!--icon="check"/>-->
<!--<span>{{ $i18n.get('approve_item') }}</span>-->
<!--</button>-->
<!--<button-->
<!--v-if="activity.status == 'publish'"-->
<!--@click="notApproveActivity"-->
<!--type="button"-->
<!--class="button is-blue5">-->
<!--<b-icon-->
<!--custom-class="mdi-flip-h"-->
<!--size="is-small"-->
<!--icon="share"/>-->
<!--<span>{{ $i18n.get('undo') }}</span>-->
<!--</button>-->
<!-- <button
v-if="activity.status == 'publish'"
@click="$parent.close()"
type="button"
class="button is-secondary">
<span>OK</span>
</button> -->
</div>
</div>
</footer>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import moment from 'moment';
import FileItem from './file-item.vue';
export default {
name: "ActivityDetailsModal",
props: {
activityId: String
},
data() {
return {
infoEmpty: `[ ${this.$i18n.get('info_empty').toLowerCase()} ]`,
dateFormat: '',
activityCreationDate: '',
placeholderSquareImage: `${tainacan_plugin.base_url}/admin/images/placeholder_square.png`,
isLoadingActivity: false,
adminFullURL: tainacan_plugin.admin_url + 'admin.php?page=tainacan_admin#',
}
},
components: {
FileItem
},
watch: {
'$route' (to, from) {
if (to !== from)
this.$parent.close();
}
},
computed: {
activity() {
return this.getActivity();
},
relatedToLink() {
switch(this.activity.object_type) {
case 'Tainacan\\Entities\\Collection':
return `${ this.$i18n.get('collection') }
<a href="${ this.adminFullURL + this.$routerHelper.getCollectionPath(this.activity.object_id) }">${ this.activity.object.name }</a>
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-collections"/></span>`;
case 'Tainacan\\Entities\\Taxonomy':
return `${ this.$i18n.get('taxonomy') }
<a href="${ this.adminFullURL + this.$routerHelper.getTaxonomyPath(this.activity.object_id) }">${ this.activity.object.name }</a>
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-taxonomies"/></span>`;
case 'Tainacan\\Entities\\Metadatum':
return `${ this.$i18n.get('metadatum') }
<a href="${ this.adminFullURL + (this.activity.object.collection_id == 'default' ? this.$routerHelper.getMetadataEditPath(this.activity.object_id) : this.$routerHelper.getCollectionMetadataEditPath(this.activity.object.collection_id, this.activity.object_id)) }">${ this.activity.object.name }</a>
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-metadata"/></span>`;
case 'Tainacan\\Entities\\Filter':
return `${ this.$i18n.get('filter') }
<a href="${ this.adminFullURL + (this.activity.object.collection_id == 'default' ? this.$routerHelper.getFilterEditPath(this.activity.object_id) : this.$routerHelper.getCollectionFilterEditPath(this.activity.object.collection_id, this.activity.object_id)) }">${ this.activity.object.name }</a>
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-filters"/></span>`;
case 'Tainacan\\Entities\\Term':
return `${ this.$i18n.get('term') }
<a href="${ this.adminFullURL + this.$routerHelper.getTermEditPath(this.activity.object.taxonomy.replace( /^\D+/g, ''), this.activity.object_id) }">${ this.activity.object.name }</a>
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-terms"/></span>`;
case 'Tainacan\\Entities\\Item':
return `${ this.$i18n.get('item') }
<a href="${ this.adminFullURL + this.$routerHelper.getItemEditPath(this.activity.object.collection_id, this.activity.object_id) }">${ this.activity.object.title }</a>
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-items"/></span>`;
case 'Tainacan\\Entities\\Item_Metadata_Entity':
return `${ this.$i18n.get('item') }
<a href="${ this.adminFullURL + this.$routerHelper.getItemEditPath(this.activity.object.collection_id, this.activity.item.id) }">${ this.activity.item.title }</a>
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-items"/></span>`;
}
}
},
created() {
this.loadActivity();
},
methods: {
...mapActions('activity', [
'fetchActivity'
]),
...mapGetters('activity', [
'getActivity'
]),
approveActivity(){
this.$emit('approveActivity', this.activity.id);
},
notApproveActivity(){
this.$emit('notApproveActivity', this.activity.id);
},
loadActivity() {
this.isLoadingActivity = true;
this.fetchActivity(this.activityId)
.then(() => {
this.isLoadingActivity = false;
let locale = navigator.language;
moment.locale(locale);
let localeData = moment.localeData();
this.dateFormat = localeData.longDateFormat('lll');
let logDate = this.activity.log_date;
let date = moment(logDate).format(this.dateFormat);
if (date != 'Invalid date') {
this.activityCreationDate = date;
} else {
this.activityCreationDate = this.$i18n.get('info_unknown_date');
}
})
.catch(() => this.isLoadingActivity = false);
}
}
}
</script>
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
.tainacan-modal-title {
align-self: baseline;
display: flex;
flex-direction: column;
width: 100%;
p {
margin-right: auto;
}
}
.tainacan-modal-content {
width: auto;
min-height: 500px;
p {
font-size: 0.875rem;
}
}
.modal-card-body {
min-height: 300px;
padding: 0;
.columns {
margin: 6px $page-side-padding 0 $page-side-padding;
}
}
.tainacan-attachments-in-modal {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-content: baseline;
resize: vertical;
overflow-y: auto;
overflow-x: hidden;
height: 200px;
border: 1px solid $gray3;
&>div {
margin: 0.5rem;
}
}
.tainacan-p-overflow {
text-overflow: ellipsis;
white-space: nowrap;
max-width: 150px;
overflow: hidden;
}
p.is-capitalized {
margin-bottom: 0.125rem;
}
.tainacan-p-break {
word-break: break-word;
margin-bottom: 0.5rem;
}
.tainacan-figure {
width: 150px;
height: 150px;
overflow: auto;
}
</style>

View File

@ -1,401 +0,0 @@
<template>
<div class="tainacan-modal-content">
<header class="tainacan-modal-title">
<h2>{{ $i18n.get('activity') }}</h2>
<hr>
</header>
<div class="modal-card-body">
<div class="content">
<p><strong>{{ $i18n.get('label_activity_description') }}:</strong> {{ activity.description }}</p>
<p><strong>{{ $i18n.get('label_activity_creation_date') }}:</strong> {{ activityCreationDate }}</p>
<p><strong>{{ $i18n.get('label_activity_author') }}:</strong> {{ activity.user_name }}</p>
</div>
<div>
<template v-for="(diff, attributeName, index) in activity.log_diffs">
<div
:key="index"
class="columns">
<!-- OLD -->
<div class="column is-6">
<!-- Thumbnail -->
<div
class="content"
v-if="attributeName == 'thumbnail'">
<p class="is-capitalized has-text-blue5">
{{ attributeName }}
<small class="has-text-gray4"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<div>
<picture>
<img
width="150px"
:src="diff.old ? diff.old : placeholderSquareImage"
:alt="attributeName">
</picture>
</div>
</div>
<div
v-if="attributeName == 'attachments'"
class="content">
<p class="is-capitalized has-text-blue5">
{{ attributeName }}
<small class="has-text-gray4"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<div
class="tainacan-attachments-in-modal"
v-if="diff.old.length">
<template v-for="(attachment, anotherIndex) in diff.old">
<file-item
:key="anotherIndex"
:modal-on-click="false"
:show-name="true"
:file="{
title: { rendered: attachment.title },
guid: { rendered: attachment.url },
mime_type: attachment.mime_type,
media_type: attachment.mime_type.includes('image') ? 'image' : 'other'
}"/>
</template>
</div>
<div v-else>
<p>{{ infoEmpty }}</p>
</div>
</div>
<div
class="content"
v-if="!['thumbnail', 'attachments'].includes(attributeName)">
<p class="is-capitalized has-text-blue5">
{{ attributeName.replace(/_/g, ' ') }}
<small class="has-text-gray4"> {{ `(${$i18n.get('info_logs_before')})` }}</small>
</p>
<!-- Is array with length 1 -->
<p
class="tainacan-p-break"
v-if="(diff.old instanceof Array) &&
(diff.old.length == 1) &&
!(diff.old[0] instanceof Object)">
{{ diff.old.toString() }}
</p>
<div
v-else-if="attributeName == 'metadata_order'"
class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in diff.old"
:key="diffTitle">
{{ diff.old ? `ID: ${diffContent.id} | Enabled: ${diffContent.enabled}` : infoEmpty }}
</p>
</div>
<div
v-else-if="attributeName == 'filters_order'"
class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in diff.old"
:key="diffTitle">
{{ diff.old ? `ID: ${diffContent.id} | Enabled: ${diffContent.enabled}` : infoEmpty }}
</p>
</div>
<div
v-else-if="attributeName == 'metadata_type_options'"
class="content">
<p class="tainacan-p-break">
{{ diff.old ?
`Taxonomy ID: ${diff.old.taxonomy_id};
Input type: ${diff.old.input_type};
Allow new terms: ${diff.old.allow_new_terms}` : infoEmpty }}
</p>
</div>
<!-- -->
<p
class="tainacan-p-break"
v-else>
{{ diff.old ? (diff.old instanceof Array && !diff.old.length) ? infoEmpty : diff.old.toString().replace(/,/g, ' ') : infoEmpty }}
</p>
</div>
</div>
<!-- NEW -->
<div class="column is-6">
<!-- Thumbnail -->
<div
class="content"
v-if="attributeName == 'thumbnail'">
<p class="is-capitalized has-text-blue5">
{{ attributeName }}
<small class="has-text-gray4"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<div>
<picture>
<img
width="150px"
:src="diff.new ? diff.new : placeholderSquareImage"
:alt="attributeName">
</picture>
</div>
</div>
<div
v-if="attributeName == 'attachments'"
class="content">
<p class="is-capitalized has-text-blue5">
{{ attributeName }}
<small class="has-text-gray4"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<div
class="tainacan-attachments-in-modal"
v-if="diff.new.length">
<template v-for="(attachment, index) in diff.new">
<file-item
:key="index"
:modal-on-click="false"
:show-name="true"
:file="{
title: { rendered: attachment.title },
guid: { rendered: attachment.url },
mime_type: attachment.mime_type,
media_type: attachment.mime_type.includes('image') ? 'image' : 'other'
}"/>
</template>
</div>
<div v-else>
<p>{{ infoEmpty }}</p>
</div>
</div>
<div
class="content"
v-if="!['thumbnail', 'attachments'].includes(attributeName)">
<p class="is-capitalized has-text-blue5">
{{ attributeName.replace(/_/g, ' ') }}
<small class="has-text-gray4"> {{ `(${$i18n.get('info_logs_after')})` }}</small>
</p>
<!-- Is array with length 1 -->
<p
class="tainacan-p-break"
v-if="(diff.new instanceof Array) &&
(diff.new.length == 1) &&
!(diff.new[0] instanceof Object)">
{{ diff.new.toString() }}
</p>
<div
v-else-if="attributeName == 'metadata_order'"
class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in diff.new"
:key="diffTitle">
{{ `ID: ${diffContent.id} | Enabled: ${diffContent.enabled}` }}
</p>
</div>
<div
v-else-if="attributeName == 'filters_order'"
class="content">
<p
class="tainacan-p-break"
v-for="(diffContent, diffTitle) in diff.new"
:key="diffTitle">
{{ `ID: ${diffContent.id} | Enabled: ${diffContent.enabled}` }}
</p>
</div>
<div
v-else-if="attributeName == 'metadata_type_options'"
class="content">
<p class="tainacan-p-break">
{{ `Taxonomy ID: ${diff.new.taxonomy_id};
Input type: ${diff.new.input_type};
Allow new terms: ${diff.new.allow_new_terms}` }}
</p>
</div>
<!-- -->
<p
class="tainacan-p-break"
v-else>
{{ diff.new ? (diff.new instanceof Array && !diff.new.length) ? infoEmpty : diff.new.toString().replace(/,/g, ' ') : infoEmpty }}
</p>
</div>
</div>
</div>
</template>
</div>
</div>
<footer>
<div class="control">
<button
class="button is-outlined"
type="button"
@click="$parent.close()">
{{ $i18n.get('close') }}
</button>
<div class="buttons is-pulled-right">
<!--<button-->
<!--v-if="activity.status != 'publish'"-->
<!--@click="notApproveActivity"-->
<!--type="button"-->
<!--class="button is-danger">-->
<!--<b-icon-->
<!--size="is-small"-->
<!--icon="close"/>-->
<!--<span>{{ $i18n.get('not_approve_item') }}</span>-->
<!--</button>-->
<!--<button-->
<!--v-if="activity.status != 'publish'"-->
<!--@click="approveActivity"-->
<!--type="button"-->
<!--class="button is-secondary">-->
<!--<b-icon-->
<!--size="is-small"-->
<!--icon="check"/>-->
<!--<span>{{ $i18n.get('approve_item') }}</span>-->
<!--</button>-->
<!--<button-->
<!--v-if="activity.status == 'publish'"-->
<!--@click="notApproveActivity"-->
<!--type="button"-->
<!--class="button is-blue5">-->
<!--<b-icon-->
<!--custom-class="mdi-flip-h"-->
<!--size="is-small"-->
<!--icon="share"/>-->
<!--<span>{{ $i18n.get('undo') }}</span>-->
<!--</button>-->
<!-- <button
v-if="activity.status == 'publish'"
@click="$parent.close()"
type="button"
class="button is-secondary">
<span>OK</span>
</button> -->
</div>
</div>
</footer>
</div>
</template>
<script>
import moment from 'moment';
import FileItem from '../file-item.vue';
export default {
name: "ActivityDetailsModal",
props: {
activity: Object
},
data() {
return {
infoEmpty: `[${this.$i18n.get('info_empty').toLowerCase()}]`,
dateFormat: '',
activityCreationDate: '',
placeholderSquareImage: `${tainacan_plugin.base_url}/admin/images/placeholder_square.png`,
}
},
components: {
FileItem
},
created() {
let locale = navigator.language;
moment.locale(locale);
let localeData = moment.localeData();
this.dateFormat = localeData.longDateFormat('lll');
let logDate = this.activity.log_date;
let date = moment(logDate).format(this.dateFormat);
if (date != 'Invalid date') {
this.activityCreationDate = date;
} else {
this.activityCreationDate = this.$i18n.get('info_unknown_date');
}
},
methods: {
approveActivity(){
this.$emit('approveActivity', this.activity.id);
},
notApproveActivity(){
this.$emit('notApproveActivity', this.activity.id);
},
undo(){
}
}
}
</script>
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
.tainacan-modal-title {
align-self: baseline;
display: flex;
flex-direction: column;
width: 100%;
}
.tainacan-modal-content {
width: auto;
min-height: 600px;
}
.modal-card-body {
min-height: 400px;
}
.tainacan-attachments-in-modal {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-content: baseline;
resize: vertical;
overflow-y: auto;
overflow-x: hidden;
height: 200px;
border: 1px solid $gray3;
&>div {
margin: 0.5rem;
}
}
.tainacan-p-overflow {
text-overflow: ellipsis;
white-space: nowrap;
max-width: 150px;
overflow: hidden;
}
.tainacan-p-break {
word-break: break-word;
}
.tainacan-figure {
width: 150px;
height: 150px;
overflow: auto;
}
</style>

View File

@ -488,7 +488,7 @@
let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
if(this.collection_id == 'default'){
route = `/facets/${this.metadatum_id}${query}`
}
@ -611,7 +611,7 @@
let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
if (this.collection_id == 'default'){
route = `/facets/${this.metadatum_id}${query}`
}
@ -648,7 +648,7 @@
let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
if (this.collection_id == 'default'){
route = `/facets/${this.metadatum_id}${query}`
}

View File

@ -227,9 +227,6 @@ RouterHelperPlugin.install = function (Vue, options = {}) {
getFiltersPath(query) {
return '/filters/?' + qs.stringify(query);
},
getMetadataPath(query) {
return '/metadata/?' + qs.stringify(query);
},
getActivitiesPath(query) {
return '/activities/?' + qs.stringify(query);
},
@ -302,14 +299,23 @@ RouterHelperPlugin.install = function (Vue, options = {}) {
getItemEditPath(collectionId, itemId) {
return '/collections/' + collectionId + '/items/' + itemId + '/edit';
},
getFilterEditPath(id) {
return '/filters/' + id + '/edit';
getMetadataEditPath(metadatumId) {
return '/metadata/?edit=' + metadatumId;
},
getFilterEditPath(filterId) {
return '/filters/?edit=' + filterId;
},
getCollectionMetadataEditPath(collectionId, metadatumId) {
return '/collections/' + collectionId + '/metadata/?edit=' + metadatumId;
},
getCollectionFilterEditPath(collectionId, filterId) {
return '/collections/' + collectionId + '/filters/?edit=' + filterId;
},
getTaxonomyEditPath(id, isRecent) {
return isRecent != undefined ? '/taxonomies/' + id + '/edit?recent=true' : '/taxonomies/' + id + '/edit';
},
getTermEditPath(taxonomyId, termId) {
return '/taxonomies/' + taxonomyId + '/terms/' + termId + '/edit';
return '/taxonomies/' + taxonomyId + '/edit?tab=terms';
},
getImporterEditionPath(importerType) {
return '/importers/' + importerType;

View File

@ -28,6 +28,74 @@
:active.sync="isLoading"
:can-cancel="false"/>
<div
v-if="tab != 'processes'"
class="sub-header">
<b-field class="header-item">
<b-datepicker
ref="datepicker"
:placeholder="$i18n.get('instruction_filter_activities_date')"
v-model="searchDates"
range
@input="searchActivities()"
:date-formatter="(date) => dateFormatter(date)"
:date-parser="(date) => dateParser(date)"
size="is-small"
icon="calendar-today"
:day-names="[
$i18n.get('datepicker_short_sunday'),
$i18n.get('datepicker_short_monday'),
$i18n.get('datepicker_short_tuesday'),
$i18n.get('datepicker_short_wednesday'),
$i18n.get('datepicker_short_thursday'),
$i18n.get('datepicker_short_friday'),
$i18n.get('datepicker_short_saturday')
]"
:month-names="[
$i18n.get('datepicker_month_january'),
$i18n.get('datepicker_month_february'),
$i18n.get('datepicker_month_march'),
$i18n.get('datepicker_month_april'),
$i18n.get('datepicker_month_may'),
$i18n.get('datepicker_month_june'),
$i18n.get('datepicker_month_july'),
$i18n.get('datepicker_month_august'),
$i18n.get('datepicker_month_september'),
$i18n.get('datepicker_month_october'),
$i18n.get('datepicker_month_november'),
$i18n.get('datepicker_month_december')
]"/>
<p
class="control"
v-if="searchDates && searchDates.length != 0">
<button
class="button"
@click="clearSearchDates()">
<span class="icon"><i class="tainacan-icon tainacan-icon-close"/></span>
</button>
</p>
</b-field>
<b-field class="header-item">
<div class="control has-icons-right is-small is-clearfix">
<input
class="input is-small"
:placeholder="$i18n.get('instruction_search')"
type="search"
:aria-label="$i18n.get('instruction_search') + ' ' + $i18n.get('activities')"
autocomplete="on"
v-model="searchQuery"
@keyup.enter="searchActivities()">
<span
@click="searchActivities()"
class="icon is-right">
<i class="tainacan-icon tainacan-icon-search" />
</span>
</div>
</b-field>
</div>
<activities-list
v-if="tab != 'processes'"
:is-loading="isLoading"
@ -149,11 +217,13 @@
<script>
import ActivitiesList from "../../components/lists/activities-list.vue";
import ProcessesList from "../../components/lists/processes-list.vue";
import { dateInter } from "../../../admin/js/mixins";
import { mapActions, mapGetters } from 'vuex';
import moment from 'moment'
export default {
name: 'ActivitiesPage',
mixins: [ dateInter ],
data(){
return {
isLoading: false,
@ -165,6 +235,8 @@
isRepositoryLevel: false,
tab: '',
isItemLevel: false,
searchQuery: '',
searchDates: []
}
},
components: {
@ -237,10 +309,15 @@
loadActivities() {
this.isLoading = true;
let dataInit = this.searchDates && this.searchDates[0] ? moment(this.searchDates[0]).format('YYYY-MM-DD') : null;
let dataEnd = this.searchDates && this.searchDates[1] ? moment(this.searchDates[1]).format('YYYY-MM-DD') : null;
if(this.isRepositoryLevel) {
this.fetchActivities({
'page': this.activitiesPage,
'activitiesPerPage': this.activitiesPerPage
'activitiesPerPage': this.activitiesPerPage,
'search': this.searchQuery,
'searchDates': [dataInit, dataEnd]
})
.then((res) => {
this.isLoading = false;
@ -253,7 +330,9 @@
this.fetchCollectionActivities({
'page': this.activitiesPage,
'activitiesPerPage': this.activitiesPerPage,
'collectionId': this.$route.params.collectionId
'collectionId': this.$route.params.collectionId,
'search': this.searchQuery,
'searchDates': [dataInit, dataEnd]
})
.then((res) => {
this.isLoading = false;
@ -266,7 +345,9 @@
this.fetchItemActivities({
'page': this.activitiesPage,
'activitiesPerPage': this.activitiesPerPage,
'itemId': this.$route.params.itemId
'itemId': this.$route.params.itemId,
'search': this.searchQuery,
'searchDates': [dataInit, dataEnd]
})
.then((res) => {
this.isLoading = false;
@ -300,6 +381,25 @@
getLastProcessesNumber() {
let last = (Number(this.processesPerPage * (this.processesPage - 1)) + Number(this.processesPerPage));
return last > this.total ? this.total : last;
},
searchActivities() {
this.activitiesPage = 1;
this.loadActivities();
},
clearSearchDates() {
this.searchDates = null;
this.searchActivities();
},
dateFormatter(dateObject) {
if (dateObject == null || dateObject.length == 0 || dateObject[0] == null || dateObject[1] == null)
return "";
return moment(dateObject[0], moment.ISO_8601).format(this.dateFormat) + " - " + moment(dateObject[1], moment.ISO_8601).format(this.dateFormat);
},
dateParser(dateString) {
return [
moment(dateString[0], this.dateFormat).toDate(),
moment(dateString[1], this.dateFormat).toDate()
];
}
},
computed: {
@ -357,15 +457,60 @@
@import '../../scss/_variables.scss';
.sub-header {
min-height: $header-height;
min-height: $subheader-height;
height: $header-height;
padding-left: 0;
padding-right: 0;
border-bottom: 1px solid #ddd;
display: inline-flex;
justify-content: space-between;
align-items: center;
width: 100%;
.header-item {
display: inline-block;
padding-right: 8em;
margin-bottom: 0 !important;
&:not(:last-child) {
padding-right: 0.5em;
}
.label {
font-size: 0.875rem;
font-weight: normal;
margin-top: 3px;
margin-bottom: 2px;
cursor: default;
}
.button {
display: flex;
align-items: center;
border-radius: 0 !important;
height: 1.95rem !important;
}
.field {
align-items: center;
}
.gray-icon, .gray-icon .icon {
color: $gray4 !important;
padding-right: 10px;
}
.gray-icon .icon i::before,
.gray-icon i::before {
font-size: 1.3125rem !important;
max-width: 26px;
}
.icon {
pointer-events: all;
cursor: pointer;
color: $blue5;
height: 27px;
font-size: 18px !important;
height: 1.5rem !important;
}
}
@media screen and (max-width: 769px) {
@ -373,8 +518,8 @@
margin-top: -0.5em;
padding-top: 0.9em;
.header-item {
padding-right: 0.5em;
.header-item:not(:last-child) {
padding-right: 0.2em;
}
}
}

View File

@ -183,3 +183,166 @@
}
}
}
.datepicker {
width: 100%;
.datepicker-content {
height: auto;
input {
height: 30px;
}
}
.dropdown-menu {
background: transparent;
border: none;
.dropdown-item {
background-color: white !important;
}
}
.datepicker-header {
.pagination {
a>span>i:before {
display: inline-block;
font: normal normal normal 20px/1 "TainacanIcons";
font-size: inherit;
text-rendering: auto;
vertical-align: middle;
line-height: inherit;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: $secondary;
}
.pagination-previous {
border: none;
flex-grow: 0;
&>span>i:before {
content: 'previous';
font-size: 20px;
}
}
.pagination-next {
border: none;
flex-grow: 0;
&>span>i:before {
content: 'next';
font-size: 20px;
}
}
}
}
.datepicker-table {
margin-bottom: 0px;
.datepicker-cell {
border: none !important;
padding: 0.5rem 0.75rem;
&.is-selectable.is-first-hovered,
&.is-selectable.is-last-hovered {
color: $gray4 !important;
background-color: $gray3 !important;
}
&.is-today,
&.is-today:hover {
color: $gray4 !important;
background-color: $turquoise1;
}
&.is-selected,
&.is-selected:hover {
color: white !important;
background-color: $turquoise5 !important;
}
}
.datepicker-months {
width: auto;
.datepicker-cell {
height: 2rem;
width: 50%;
padding: 0.3rem 0.25rem !important;
text-overflow: ellipsis;
overflow: hidden;
display: block;
}
}
}
@media screen and (min-width: 1024px) {
.datepicker-header {
margin-bottom: 0.5rem;
padding-top: 0.15rem;
padding-bottom: 0.5rem;
.pagination {
flex-wrap: wrap;
.pagination-list {
margin-bottom: 0.5rem;
.field.has-addons {
width: 100% !important;
.control {
height: 24px !important;
}
}
}
.pagination-previous {
margin: 0;
height: 24px;
padding: 0;
font-size: 0.75rem;
order: 3;
}
.pagination-next {
margin: 0;
height: 24px;
padding: 0;
font-size: 0.75rem;
}
}
}
.dropdown-item {
padding: 0.8rem !important;
}
.dropdown-menu {
min-width: 100% !important;
}
.datepicker-table {
margin-bottom: 0px;
}
.select {
select {
display: unset;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.dropdown-content {
border-radius: 2px !important;
padding: 0px;
max-height: inherit !important;
}
}
}

View File

@ -183,13 +183,13 @@
h4 {
font-weight: 600;
color: #298596;
color: $turquoise5;
margin-bottom: 6px;
}
hr {
margin-top: 8px;
height: 1px;
background-color: #298596;
background-color: $turquoise5;
}
}
}

View File

@ -435,6 +435,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_day' => __( 'Day', 'tainacan' ),
'label_month' => __( 'Month', 'tainacan' ),
'label_year' => __( 'Year', 'tainacan' ),
'label_related_to' => __( 'Related to', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -479,11 +480,12 @@ return apply_filters( 'tainacan-admin-i18n', [
'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' ),
'instruction_filter_activities_date' => __( 'Range of dates', 'tainacan'),
'instruction_select_a_date' => __( 'Select a date', 'tainacan' ),
'instruction_select_a_month' => __( 'Select a month', 'tainacan' ),
'instruction_type_value_year' => __( 'Type year value', 'tainacan' ),
'instruction_select_the_amount_of_copies' => __( 'Select the amount of copies of the item that you want to create', 'tainacan'),
'instruction_select_a_interval' => __( 'Select a interval', 'tainacan'),
'instruction_select_a_interval' => __( 'Select an interval', 'tainacan'),
// Info. Other feedback to user.

View File

@ -148,7 +148,7 @@ class REST_Filters_Controller extends REST_Controller {
$filter_obj->set_metadatum_id($body['metadatum_id']);
} else {
$filter_obj->set_collection_id( 'filter_in_repository' );
$filter_obj->set_collection_id( 'default' );
if(!isset($body['metadatum_id'])){
throw new \InvalidArgumentException('You need provide a metadatum id');
@ -375,7 +375,7 @@ class REST_Filters_Controller extends REST_Controller {
if(!isset($request['collection_id'])) {
$args['meta_query'][] = [
'key' => 'collection_id',
'value' => 'filter_in_repository',
'value' => 'default',
'compare' => '='
];

View File

@ -17,12 +17,6 @@ class REST_Logs_Controller extends REST_Controller {
public function __construct() {
$this->rest_base = 'logs';
parent::__construct();
add_action('init', array($this, 'init_objects'));
}
public function init_objects(){
$this->logs_repository = Repositories\Logs::get_instance();
$this->log = new Entities\Log();
}
public function register_routes() {
@ -32,7 +26,7 @@ class REST_Logs_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params()
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::READABLE)
)
)
);
@ -46,15 +40,6 @@ class REST_Logs_Controller extends REST_Controller {
)
)
);
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<log_id>[\d]+)/approve',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array($this, 'approve_item'),
'permission_callback' => array($this, 'approve_item_permissions_check'),
)
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base,
array(
array(
@ -75,6 +60,46 @@ class REST_Logs_Controller extends REST_Controller {
)
)
);
register_rest_route($this->namespace, '/filter/(?P<filter_id>[\d]+)/' . $this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
)
);
register_rest_route($this->namespace, '/metadatum/(?P<metadatum_id>[\d]+)/' . $this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
)
);
register_rest_route($this->namespace, '/taxonomy/(?P<taxonomy_id>[\d]+)/' . $this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
)
);
register_rest_route($this->namespace, '/term/(?P<term_id>[\d]+)/' . $this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
)
);
}
/**
@ -86,12 +111,120 @@ class REST_Logs_Controller extends REST_Controller {
public function prepare_item_for_response( $item, $request ) {
if(!empty($item)){
// Hanle logs created before 1.0
if ( !empty( get_post_meta($item->get_id(), 'value', true) ) && !empty( get_post_meta($item->get_id(), 'log_diffs', true) ) ) {
return $this->prepare_legacy_item_for_response($item, $request);
}
if ($request['log_id']) {
$item_array = $item->_toArray();
$related_object = true;
if ($item_array['item_id']) {
$item = Repositories\Items::get_instance()->fetch( (int) $item_array['item_id'] );
if ($item instanceof Entities\Item ) {
$item_array['item'] = $item->_toArray();
}
}
if ($item_array['collection_id']) {
$collection = Repositories\Collections::get_instance()->fetch( (int) $item_array['collection_id'] );
if ($collection instanceof Entities\Item ) {
$item_array['collection'] = $collection->_toArray();
}
}
if ( $item_array['object_id'] ) {
if ( $item_array['object_type'] == 'Tainacan\Entities\Term' ) {
$related_entity = Repositories\Terms::get_instance()->fetch( (int) $item_array['object_id'] );
} else {
$related_post = get_post($item_array['object_id']);
$related_entity = Repository::get_entity_by_post( $related_post );
}
if ($related_entity instanceof Entities\Entity ) {
$item_array[ 'object' ] = $related_entity->_toArray();
}
}
if ( $item_array['action'] == 'new-attachment' ) {
if ( isset($item_array['new_value']['id']) ) {
$item_array['new_value']['url'] = wp_get_attachment_url($item_array['new_value']['id']);
$item_array['new_value']['thumb'] = wp_get_attachment_image_src($item_array['new_value']['id'], 'thumbnail');
}
} elseif ( $item_array['action'] == 'update-document' ) {
if ( isset( $item_array['new_value']['document'] ) && is_numeric( $item_array['new_value']['document'] ) ) {
$item_array['new_value']['url'] = wp_get_attachment_url($item_array['new_value']['document']);
$item_array['new_value']['thumb'] = wp_get_attachment_image_src($item_array['new_value']['document'], 'thumbnail');
}
if ( isset( $item_array['old_value']['document'] ) && is_numeric( $item_array['old_value']['document'] ) ) {
$item_array['old_value']['url'] = wp_get_attachment_url($item_array['old_value']['document']);
$item_array['old_value']['thumb'] = wp_get_attachment_image_src($item_array['old_value']['document'], 'thumbnail');
}
} elseif ( $item_array['action'] == 'update-thumbnail' ) {
if ( isset( $item_array['new_value']['_thumbnail_id'] ) ) {
$item_array['new_value']['url'] = wp_get_attachment_url($item_array['new_value']['_thumbnail_id']);
$item_array['new_value']['thumb'] = wp_get_attachment_image_src($item_array['new_value']['_thumbnail_id'], 'thumbnail');
}
if ( isset( $item_array['old_value']['_thumbnail_id'] ) ) {
$item_array['old_value']['url'] = wp_get_attachment_url($item_array['old_value']['_thumbnail_id']);
$item_array['old_value']['thumb'] = wp_get_attachment_image_src($item_array['old_value']['_thumbnail_id'], 'thumbnail');
}
}
// translate
if (isset($related_entity) && $related_entity instanceof Entities\Entity ) {
$map = $related_entity->get_repository()->get_map();
foreach ( $map as $slug => $m ) {
if ( isset($item_array['new_value'][$slug]) ) {
$item_array['new_value'][$m['title']] = $item_array['new_value'][$slug];
unset($item_array['new_value'][$slug]);
}
if ( isset($item_array['old_value'][$slug]) ) {
$item_array['old_value'][$m['title']] = $item_array['old_value'][$slug];
unset($item_array['old_value'][$slug]);
}
}
}
return $item_array;
} else {
if(!isset($request['fetch_only'])) {
$item_array = $item->_toArray();
return $item_array;
}
$attributes_to_filter = $request['fetch_only'];
}
return $this->filter_object_by_attributes($item, $attributes_to_filter);
}
return $item;
}
private function prepare_legacy_item_for_response($item, $request) {
if(!isset($request['fetch_only'])) {
$item_array = $item->_toArray();
unset($item_array['value']);
unset($item_array['old_value']);
$item_array['legacy'] = true;
return $item_array;
}
@ -100,9 +233,6 @@ class REST_Logs_Controller extends REST_Controller {
return $this->filter_object_by_attributes($item, $attributes_to_filter);
}
return $item;
}
/**
* @param \WP_REST_Request $request
*
@ -115,90 +245,27 @@ class REST_Logs_Controller extends REST_Controller {
if ($request['item_id']) {
$item_id = $request['item_id'];
$item_repository = Repositories\Items::get_instance();
$item = $item_repository->fetch($item_id);
if(!$item){
return new \WP_REST_Response([
'error_message' => __('An item with this ID does not exist', 'tainacan'),
'item_id' => $item
], 400);
$args['item_id'] = $request['item_id'];
} elseif ($request['collection_id']) {
$args['collection_id'] = $request['collection_id'];
} elseif ($request['filter_id']) {
$args['object_type'] = 'Tainacan\Entities\Filter';
$args['object_id'] = $request['filter_id'];
} elseif ($request['metadatum_id']) {
$args['object_type'] = 'Tainacan\Entities\Metadatum';
$args['object_id'] = $request['metadatum_id'];
} elseif ($request['taxonomy_id']) {
$args['object_type'] = 'Tainacan\Entities\Taxonomy';
$args['object_id'] = $request['taxonomy_id'];
} elseif ($request['term_id']) {
$args['object_type'] = 'Tainacan\Entities\Term';
$args['object_id'] = $request['term_id'];
}
if($args &&
array_key_exists('meta_query', $args) &&
array_key_exists('relation', $args['meta_query'])){
$metaq = $args['meta_query'];
unset($args['meta_query']);
$args['meta_query'][] = $metaq;
$args['meta_query']['relation'] = 'AND';
} elseif($args &&
array_key_exists('meta_query', $args)){
$args['meta_query']['relation'] = 'AND';
}
$args = array_merge_recursive(array(
'meta_query' => array(
'item_clause' => array(
'key' => 'item_id',
'value' => $item_id,
'compare' => '='
)
)
), $args);
}
if($request['collection_id']){
$collection_id = $request['collection_id'];
$collection_repository = Repositories\Collections::get_instance();
$collection = $collection_repository->fetch($collection_id);
if(!$collection){
return new \WP_REST_Response([
'error_message' => __('A collection with this ID does not exist', 'tainacan'),
'collection_id' => $collection_id
], 400);
}
if($args &&
array_key_exists('meta_query', $args) &&
array_key_exists('relation', $args['meta_query'])){
$metaq = $args['meta_query'];
unset($args['meta_query']);
$args['meta_query'][] = $metaq;
$args['meta_query']['relation'] = 'AND';
} elseif($args &&
array_key_exists('meta_query', $args)){
$args['meta_query']['relation'] = 'AND';
}
$args = array_merge_recursive(array(
'meta_query' => array(
'collection_clause' => array(
'key' => 'collection_id',
'value' => $collection_id,
'compare' => '='
)
)
), $args);
}
$logs = $this->logs_repository->fetch($args);
$logs = Repositories\Logs::get_instance()->fetch($args);
$response = [];
if($logs->have_posts()){
while ($logs->have_posts()){
$logs->the_post();
@ -228,6 +295,7 @@ class REST_Logs_Controller extends REST_Controller {
* @return bool|\WP_Error
*/
public function get_items_permissions_check( $request ) {
return true;
return current_user_can('read');
}
@ -239,7 +307,7 @@ class REST_Logs_Controller extends REST_Controller {
public function get_item( $request ) {
$log_id = $request['log_id'];
$log = $this->logs_repository->fetch($log_id);
$log = Repositories\Logs::get_instance()->fetch($log_id);
$prepared_log = $this->prepare_item_for_response( $log, $request );
@ -252,7 +320,8 @@ class REST_Logs_Controller extends REST_Controller {
* @return bool|\WP_Error
*/
public function get_item_permissions_check( $request ) {
$log = $this->logs_repository->fetch($request['log_id']);
return true;
$log = Repositories\Logs::get_instance()->fetch($request['log_id']);
if(($log instanceof Entities\Log)) {
if('edit' === $request['context'] && !$log->can_read()) {
@ -265,51 +334,7 @@ class REST_Logs_Controller extends REST_Controller {
return false;
}
/**
* @param \WP_REST_Request $request
*
* @return bool|\WP_Error
*/
public function approve_item_permissions_check( $request ) {
$log = $this->logs_repository->fetch($request['log_id']);
if($log instanceof Entities\Log){
if($log->can_read()) {
$entity = $log->get_value();
if($entity instanceof Entities\Entity) {
if($entity instanceof Entities\Item_Metadata_Entity) {
$item = $entity->get_item();
return $item->can_edit();
} // TODO for other entities types
else {
return $entity->can_edit();
}
}
return new \WP_Error();
}
}
return false;
}
/**
* approve a logged modification
* @param \WP_REST_Request $request
*
* @return \WP_Error|\WP_REST_Response
*/
public function approve_item($request) {
$log = $this->logs_repository->fetch($request['log_id']);
if($log instanceof Entities\Log){
$entity = $log->approve();
$prepared_entity = $this->prepare_item_for_response( $entity, $request );
return new \WP_REST_Response($prepared_entity, 200);
}
}
/**
* @param string $method
@ -328,29 +353,6 @@ class REST_Logs_Controller extends REST_Controller {
return $endpoint_args;
}
/**
*
* Return the queries supported when getting a collection of objects
*
* @param null $object_name
*
* @return array
*/
public function get_collection_params($object_name = null) {
$query_params['context']['default'] = 'view';
$query_params = array_merge($query_params, parent::get_collection_params('log'));
$query_params['title'] = array(
'description' => __('Limits the result set to a log with a specific title'),
'type' => 'string',
);
$query_params = array_merge($query_params, parent::get_meta_queries_params());
return $query_params;
}
}
?>

View File

@ -31,7 +31,7 @@ class Private_Files {
add_filter('image_get_intermediate_size', [$this, 'image_get_intermediate_size'], 10, 3);
add_filter('wp_get_attachment_url', [$this, 'wp_get_attachment_url'], 10, 2);
add_action('tainacan-insert', [$this, 'update_item_and_collection'], 10, 3);
add_action('tainacan-insert', [$this, 'update_item_and_collection']);
add_action('tainacan-bulk-edit-set-status', [$this, 'bulk_edit'], 10, 4);
@ -276,10 +276,7 @@ class Private_Files {
* if the items upload directory mus be renamed to add or remove the
* private folder prefix
*/
function update_item_and_collection($obj, $diffs, $is_update) {
// updating collection or item
if ( $is_update ) {
function update_item_and_collection($obj) {
$folder = DIRECTORY_SEPARATOR;
$check_folder = DIRECTORY_SEPARATOR;
@ -330,7 +327,6 @@ class Private_Files {
}
}
}

View File

@ -12,14 +12,17 @@ class Log extends Entity {
protected
$title,
$order,
$parent,
$description,
$blog_id,
$user_id,
$log_date,
$date,
$user_name,
$collection_id,
$item_id;
$item_id,
$object_type,
$object_id,
$old_value,
$new_value;
static $post_type = 'tainacan-log';
/**
@ -34,7 +37,6 @@ class Log extends Entity {
if ( is_int( $which ) && $which == 0 ) {
$this->set_user_id();
$this->set_blog_id();
}
}
@ -89,27 +91,10 @@ class Log extends Entity {
*
* @return mixed|null
*/
function get_log_date() {
return $this->get_mapped_property( 'log_date' );
function get_date() {
return $this->get_mapped_property( 'date' );
}
/**
* Return the log order type
*
* @return string
*/
function get_order() {
return $this->get_mapped_property( 'order' );
}
/**
* Retun the parent ID
*
* @return integer
*/
function get_parent() {
return $this->get_mapped_property( 'parent' );
}
/**
* Return the Log description
@ -120,15 +105,6 @@ class Log extends Entity {
return $this->get_mapped_property( 'description' );
}
/**
* Return the ID of blog
*
* @return integer
*/
function get_blog_id() {
return $this->get_mapped_property( 'blog_id' );
}
/**
* Return User Id of who make the action
*
@ -138,27 +114,28 @@ class Log extends Entity {
return $this->get_mapped_property( 'user_id' );
}
/**
* Get value of log entry
* Get old value of log entry object
*
* @param mixed $value
*
* @return void
*/
public function get_value() {
return maybe_unserialize( base64_decode( $this->get_mapped_property( 'value' ) ) );
public function get_old_value() {
return $this->get_mapped_property( 'old_value' );
}
// /**
// * Get old value of log entry object
// *
// * @param mixed $value
// *
// * @return void
// */
// public function get_old_value() {
// return maybe_unserialize( base64_decode( $this->get_mapped_property( 'old_value' ) ) );
// }
/**
* Get new value of log entry object
*
* @param mixed $value
*
* @return void
*/
public function get_new_value() {
return $this->get_mapped_property( 'new_value' );
}
/**
* Set log tittle
@ -167,30 +144,8 @@ class Log extends Entity {
*
* @return void
*/
function set_title( $value ) {
$this->set_mapped_property( 'title', $value );
}
/**
* Define the order type
*
* @param [string] $value
*
* @return void
*/
function set_order( $value ) {
$this->set_mapped_property( 'order', $value );
}
/**
* Define the parent ID
*
* @param [integer] $value
*
* @return void
*/
function set_parent( $value ) {
$this->set_mapped_property( 'parent', $value );
public function set_title( $value ) {
$this->set_mapped_property( 'title', apply_filters('tainacan-log-set-title', $value) );
}
/**
@ -200,7 +155,7 @@ class Log extends Entity {
*
* @return void
*/
function set_description( $value ) {
public function set_description( $value ) {
$this->set_mapped_property( 'description', $value );
}
@ -211,7 +166,7 @@ class Log extends Entity {
*
* @return void
*/
protected function set_user_id( $value = 0 ) {
public function set_user_id( $value = 0 ) {
if ( 0 == $value ) {
$value = get_current_user_id();
}
@ -219,46 +174,25 @@ class Log extends Entity {
}
/**
* Define the blog ID of log entry
*
* @param [integer] $value
*
* @return void
*/
protected function set_blog_id( $value = 0 ) {
if ( 0 == $value ) {
$value = get_current_blog_id();
}
$this->set_mapped_property( 'blog_id', $value );
}
/**
* Define the value of log entry
* Set old value of log entry
*
* @param [mixed] $value
*
* @return void
*/
protected function set_value( $value = null ) {
$this->set_mapped_property( 'value', base64_encode( maybe_serialize( $value ) ) );
public function set_old_value( $value ) {
$this->set_mapped_property( 'old_value', $value );
}
// /**
// * Set old value of log entry
// *
// * @param [mixed] $value
// *
// * @return void
// */
// protected function set_old_value( $value = null ) {
// $this->set_mapped_property( 'old_value', base64_encode( maybe_serialize( $value ) ) );
// }
/**
* @param $diffs
* Set new value of log entry
*
* @param [mixed] $value
*
* @return void
*/
public function set_log_diffs($diffs){
$this->set_mapped_property( 'log_diffs', $diffs );
public function set_new_value( $value ) {
$this->set_mapped_property( 'new_value', $value );
}
/**
@ -268,55 +202,20 @@ class Log extends Entity {
return $this->get_mapped_property('log_diffs');
}
/**
*
* @param bool $message
* @param string $desc
* @param null $value
* @param array $diffs
* @param string $status 'publish', 'private', 'pending', 'processing' or 'error'
* @param int $parent
*
* @return \Tainacan\Entities\Log | bool
* @throws \Exception
*/
public static function create( $message = false, $desc = '', $value = null, $diffs = [], $status = 'publish', $parent = 0 ) {
$log = new Log();
$log->set_title( $message );
$log->set_description( $desc );
$log->set_status( $status );
$log->set_log_diffs( $diffs );
if($parent > 0) {
$log->set_parent($parent);
public function get_object_type() {
$this->get_mapped_property('object_type');
}
if(is_object($value) || is_string($value)) {
if(array_search( 'Tainacan\Traits\Entity_Collection_Relation', class_uses($value))) {
$log->set_collection_id( $value->get_collection_id() );
} elseif($value instanceof Collection){
$log->set_collection_id( $value->get_id());
} elseif($value instanceof Item_Metadata_Entity){
$log->set_item_id($value->get_item()->get_id());
$log->set_collection_id($value->get_item()->get_collection_id());
}
public function set_object_type($value) {
$this->set_mapped_property('object_type', $value);
}
if ( ! is_null( $value ) ) {
$log->set_value( $value );
} elseif ( $message === false ) {
throw new \Exception( 'Message or value is needed to log' );
public function get_object_id() {
$this->get_mapped_property('object_id');
}
$Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance();
if ( $log->validate() ) {
return $Tainacan_Logs->insert( $log );
} else {
throw new \Exception( 'Invalid log' );
}
public function set_object_id($value) {
$this->set_mapped_property('object_id', $value);
}
/**
@ -333,6 +232,14 @@ class Log extends Entity {
return $this->get_mapped_property('item_id');
}
public function get_action() {
$this->get_mapped_property('action');
}
public function set_action($value) {
$this->set_mapped_property('action', $value);
}
/**
* {@inheritDoc}
* @see \Tainacan\Repositories\Logs::approve

View File

@ -52,7 +52,7 @@
let endpoint = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if(this.isRepositoryLevel || this.collection == 'filter_in_repository'){
if (this.isRepositoryLevel || this.collection == 'default'){
endpoint = '/metadata/'+ this.metadatum;
}

View File

@ -50,7 +50,7 @@
let route = '/collection/' + this.collection + '/metadata/' + this.metadatum +'?nopaging=1';
if (this.isRepositoryLevel || this.collection == 'filter_in_repository')
if (this.isRepositoryLevel || this.collection == 'default')
route = '/metadata?nopaging=1';
axios.get(route)

View File

@ -78,7 +78,7 @@
let endpoint = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if (this.isRepositoryLevel || this.collection == 'filter_in_repository'){
if (this.isRepositoryLevel || this.collection == 'default'){
endpoint = '/metadata/'+ this.metadatum;
}

View File

@ -122,7 +122,7 @@
let endpoint = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if (this.isRepositoryLevel || this.collection == 'filter_in_repository')
if (this.isRepositoryLevel || this.collection == 'default')
endpoint = '/metadata/'+ this.metadatum;
axios.get(endpoint)

View File

@ -47,7 +47,7 @@ export const filter_type_mixin = {
let query_items = { 'current_query': currentQuery };
let url = '';
if (isRepositoryLevel || this.filter.collection_id == 'filter_in_repository')
if (isRepositoryLevel || this.filter.collection_id == 'default')
url = `/facets/${metadatumId}?getSelected=${getSelected}&`;
else
url = `/collection/${this.filter.collection_id}/facets/${metadatumId}?getSelected=${getSelected}&`;
@ -126,7 +126,7 @@ export const filter_type_mixin = {
let query_items = { 'current_query': currentQuery };
let url = '';
if (isRepositoryLevel || this.filter.collection_id == 'filter_in_repository')
if (isRepositoryLevel || this.filter.collection_id == 'default')
url = '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`;
else
url = '/collection/' + this.filter.collection_id + '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`;

View File

@ -81,7 +81,7 @@
let endpoint = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if (this.isRepositoryLevel || this.collection == 'filter_in_repository')
if (this.isRepositoryLevel || this.collection == 'default')
endpoint = '/metadata/'+ this.metadatum;
axios.get(endpoint)

View File

@ -36,7 +36,7 @@
let endpoint = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if(this.isRepositoryLevel || this.collection == 'filter_in_repository'){
if (this.isRepositoryLevel || this.collection == 'default'){
endpoint = '/metadata/'+ this.metadatum;
}

View File

@ -55,7 +55,7 @@
let endpoint = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if(this.isRepositoryLevel || this.collection == 'filter_in_repository'){
if (this.isRepositoryLevel || this.collection == 'default'){
endpoint = '/metadata/'+ this.metadatum + '?nopaging=1';
}

View File

@ -72,185 +72,6 @@
.filter-item-forms {
.datepicker {
width: 100%;
.datepicker-content {
height: auto;
input {
height: 30px;
}
}
.dropdown-menu {
background: transparent;
border: none;
.dropdown-item {
background-color: white !important;
}
}
.datepicker-header {
.pagination {
a>span>i:before {
display: inline-block;
font: normal normal normal 20px/1 "TainacanIcons";
font-size: inherit;
text-rendering: auto;
vertical-align: middle;
line-height: inherit;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: $secondary;
}
.pagination-previous {
border: none;
flex-grow: 0;
&>span>i:before {
content: 'previous';
font-size: 20px;
}
}
.pagination-next {
border: none;
flex-grow: 0;
&>span>i:before {
content: 'next';
font-size: 20px;
}
}
}
}
.datepicker-table {
margin-bottom: 0px;
.datepicker-cell {
border: none !important;
padding: 0.5rem 0.75rem !important;
}
.datepicker-cell.is-today,
.datepicker-cell.is-today:hover {
color: $gray4 !important;
background-color: $turquoise1;
}
.datepicker-cell.is-selected,
.datepicker-cell.is-selected:hover {
color: white !important;
background-color: $turquoise5 !important;
}
.datepicker-months {
width: auto;
.datepicker-cell {
height: 2rem;
width: 50%;
padding: 0.3rem 0.25rem !important;
text-overflow: ellipsis;
overflow: hidden;
display: block;
}
}
}
@media screen and (min-width: 1024px) {
.datepicker-header {
margin-bottom: 0.5rem;
padding-top: 0.15rem;
padding-bottom: 0.5rem;
.pagination {
flex-wrap: wrap;
.pagination-list {
margin-bottom: 0.5rem;
.field.has-addons {
width: 100% !important;
.control {
height: 24px !important;
width: 74px !important;
.select {
min-width: 100% !important;
select {
padding-left: 1px !important;
font-size: 0.75rem !important;
height: 24px !important;
min-width: 100% !important;
&:not(.is-loading)::after {
margin-top: -13px !important;
}
}
}
}
}
}
.pagination-previous {
margin: 0;
height: 24px;
padding: 0;
font-size: 0.75rem;
order: 3;
}
.pagination-next {
margin: 0;
height: 24px;
padding: 0;
font-size: 0.75rem;
}
}
}
.dropdown-item {
padding: 0.8rem !important;
}
.dropdown-menu {
min-width: 100% !important;
max-width: 165px !important;
}
.datepicker-table {
margin-bottom: 0px;
.datepicker-cell {
padding: 0.15rem 0.175rem !important;
}
}
.select {
select {
display: unset;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.dropdown-content {
max-width: 165px !important;
border-radius: 2px !important;
padding: 0px;
max-height: inherit !important;
}
}
}
.collapse-trigger {
margin-left: -5px;
.icon {
@ -360,5 +181,37 @@
margin-right: 2px;
}
.datepicker {
@media screen and (min-width: 1024px) {
.datepicker-header {
.dropdown-menu {
max-width: 165px !important;
}
.pagination .pagination-list .control {
width: 74px !important;
.select {
min-width: 100% !important;
select {
padding-left: 1px !important;
font-size: 0.75rem !important;
height: 24px !important;
min-width: 100% !important;
&:not(.is-loading)::after {
margin-top: -13px !important;
}
}
}
}
}
.datepicker-cell {
padding: 0.15rem 0.175rem !important;
}
}
}
}
</style>

View File

@ -124,7 +124,7 @@
let route = '';
if(this.collection == 'filter_in_repository')
if (this.collection == 'default')
route = `/facets/${this.metadatum}?getSelected=1&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items);
else
route = `/collection/${this.collection}/facets/${this.metadatum}?getSelected=1&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items);
@ -218,7 +218,7 @@
// let route = '';
// if (this.collection == 'filter_in_repository')
// if (this.collection == 'default')
// route = '/facets/' + this.metadatum +`?term_id=${selected}&fetch_only=name,id`;
// else
// route = '/collection/'+ this.collection +'/facets/' + this.metadatum +`?term_id=${selected}&fetch_only=name,id`;

View File

@ -47,7 +47,7 @@
let endpoint = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if (this.isRepositoryLevel || this.collection == 'filter_in_repository'){
if (this.isRepositoryLevel || this.collection == 'default'){
endpoint = '/metadata/'+ this.metadatum;
}

View File

@ -217,6 +217,10 @@ class Taxonomy extends Metadata_Type {
$count ++;
if ( is_integer($term) ) {
$term = \Tainacan\Repositories\Terms::get_instance()->fetch($term, $this->get_option('taxonomy_id'));
}
if ( $term instanceof \Tainacan\Entities\Term ) {
$return .= $prefix;

View File

@ -45,7 +45,7 @@ class Text extends Metadata_Type {
public function get_value_as_html(\Tainacan\Entities\Item_Metadata_Entity $item_metadata) {
$value = $item_metadata->get_value();
$return = '';
if ( $item_metadata->is_multiple() ) {
if ( is_array($value) && $item_metadata->is_multiple() ) {
$total = sizeof($value);
$count = 0;
$prefix = $item_metadata->get_multivalue_prefix();

View File

@ -141,18 +141,18 @@ class Collections extends Repository {
],
'metadata_order' => [
'map' => 'meta',
'title' => __( 'Ordination metadata', 'tainacan' ),
'title' => __( 'Metadata order', 'tainacan' ),
'type' => 'array/object/string',
'items' => [ 'type' => 'array/string/integer/object' ],
'description' => __( 'Collection metadata ordination', 'tainacan' ),
'description' => __( 'The order of the metadata in the collection', 'tainacan' ),
//'validation' => v::stringType(),
],
'filters_order' => [
'map' => 'meta',
'title' => __( 'Ordination filters', 'tainacan' ),
'title' => __( 'Filters order', 'tainacan' ),
'type' => 'array/object/string',
'items' => [ 'type' => 'array/string/integer/object' ],
'description' => __( 'Collection filters ordination', 'tainacan' ),
'description' => __( 'The order of the filters in the collection', 'tainacan' ),
//'validation' => v::stringType(),
],
'enable_cover_page' => [

View File

@ -365,7 +365,7 @@ class Filters extends Repository {
$parents[] = $collection_id;
//search for default metadatum
$parents[] = 'filter_in_repository';
$parents[] = 'default';
$meta_query = array(
'key' => 'collection_id',
@ -416,7 +416,7 @@ class Filters extends Repository {
$parents[] = $collection_id;
//search for default metadatum
$parents[] = 'filter_in_repository';
$parents[] = 'default';
$meta_query = array(
'key' => 'collection_id',

View File

@ -37,25 +37,11 @@ class Item_Metadata extends Repository {
// TODO: Throw Warning saying you must validate object before insert()
}
$is_update = true;
do_action( 'tainacan-pre-insert', $item_metadata );
do_action( 'tainacan-pre-insert-Item_Metadata_Entity', $item_metadata );
$new = $item_metadata->get_value();
$diffs = [];
if ($this->use_logs) {
$old = get_post_meta( $item_metadata->get_item()->get_id(), $item_metadata->get_metadatum()->get_id(), true );
if($old != $new) {
$diffs['value'] = [
'new' => $new,
'old' => $old,
'diff_with_index' => [],
];
} else {
$diffs['value'] = [];
}
}
$unique = ! $item_metadata->is_multiple();
$metadata_type = $item_metadata->get_metadatum()->get_metadata_type_object();
@ -106,13 +92,10 @@ class Item_Metadata extends Repository {
}
}
if ($this->use_logs) {
$this->logs_repository->insert_log( $item_metadata, $diffs, $is_update );
}
do_action( 'tainacan-insert', $item_metadata, $diffs, $is_update );
do_action( 'tainacan-insert', $item_metadata );
do_action( 'tainacan-insert-Item_Metadata_Entity', $item_metadata );
}
$new_entity = new Entities\Item_Metadata_Entity( $item_metadata->get_item(), $item_metadata->get_metadatum() );
@ -164,11 +147,6 @@ class Item_Metadata extends Repository {
$taxonomy = new Entities\Taxonomy( $metadata_type->get_option( 'taxonomy_id' ) );
if ( $taxonomy ) {
if ( $this->use_logs ) {
$old = wp_get_object_terms( $item_metadata->get_item()->get_id(), $taxonomy->get_db_identifier(), [
'fields' => 'names'
] );
}
// We can not simply use wp_set_object_terms() because it uses term_exists() which is not reliable
// see https://core.trac.wordpress.org/ticket/45333 and https://core.trac.wordpress.org/ticket/47099
@ -200,26 +178,6 @@ class Item_Metadata extends Repository {
$success = wp_set_object_terms( $item_metadata->get_item()->get_id(), $insert, $taxonomy->get_db_identifier() );
if ( $this->use_logs && ! $success instanceof \WP_Error ) {
$new = get_terms(array(
'taxonomy' => $taxonomy->get_db_identifier(),
'hide_empty' => false,
'object_ids' => $item_metadata->get_item()->get_id(),
'fields' => 'names',
));
$diffs[ 'value' ] = [
'new' => $new,
'old' => $old,
'diff_with_index' => []
];
if($this->use_logs){
$this->logs_repository->insert_log( $item_metadata, $diffs, true );
//do_action( 'tainacan-insert', $item_metadata, $diffs, true );
}
}
}
}
}

View File

@ -16,6 +16,9 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Logs extends Repository {
public $entities_type = '\Tainacan\Entities\Log';
private static $instance = null;
private $current_diff = null;
private $current_deleting_entity;
private $current_action;
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
@ -29,7 +32,17 @@ class Logs extends Repository {
protected function __construct() {
parent::__construct();
add_action( 'add_attachment', array( $this, 'prepare_attachment_log_before_insert' ), 10 );
add_action( 'tainacan-pre-insert', array( $this, 'pre_insert_entity' ) );
add_action( 'tainacan-insert', array( $this, 'insert_entity' ) );
add_action( 'tainacan-deleted', array( $this, 'delete_entity' ), 10, 2 );
add_action( 'tainacan-pre-delete', array( $this, 'pre_delete_entity' ), 10, 2 );
add_action( 'add_attachment', array( $this, 'insert_attachment' ) );
add_action( 'delete_attachment', array( $this, 'pre_delete_attachment' ) );
add_action( 'delete_post', array( $this, 'delete_attachment' ) );
add_filter('tainacan-log-set-title', [$this, 'filter_log_title']);
}
protected function _get_map() {
@ -42,26 +55,12 @@ class Logs extends Repository {
'on_error' => __( 'The title should be a text value and not empty', 'tainacan' ),
'validation' => ''
],
'log_date' => [
'date' => [
'map' => 'post_date',
'title' => __( 'Log date', 'tainacan' ),
'type' => 'string',
'description' => __( 'The log date', 'tainacan' ),
],
'order' => [
'map' => 'menu_order',
'title' => __( 'Menu order', 'tainacan' ),
'type' => 'string',
'description' => __( 'Log order' ),
'validation' => ''
],
'parent' => [
'map' => 'parent',
'title' => __( 'Parent', 'tainacan' ),
'type' => 'string',
'description' => __( 'Log order' ),
'validation' => ''
],
'description' => [
'map' => 'post_content',
'title' => __( 'Description', 'tainacan' ),
@ -77,13 +76,6 @@ class Logs extends Repository {
'description' => __( 'The log slug' ),
'validation' => ''
],
'items_per_page' => [
'map' => 'meta',
'title' => __( 'Items per page', 'tainacan' ),
'type' => 'integer',
'description' => __( 'The quantity of items that should be loaded' ),
'validation' => ''
],
'user_id' => [
'map' => 'post_author',
'title' => __( 'User ID', 'tainacan' ),
@ -91,21 +83,19 @@ class Logs extends Repository {
'description' => __( 'Unique identifier' ),
'validation' => ''
],
'blog_id' => [
'item_id' => [
'map' => 'meta',
'title' => __( 'Blog ID', 'tainacan' ),
'title' => __( 'Item ID', 'tainacan' ),
'type' => 'integer',
'description' => __( 'Unique identifier' ),
'validation' => ''
],
'value' => [
'map' => 'meta',
'title' => __( 'Actual value', 'tainacan' ),
'type' => 'string',
'description' => __( 'The actual log value' ),
'validation' => ''
],
'log_diffs' => [
// 'value' => [
// 'map' => 'meta',
// 'title' => __( 'Actual value', 'tainacan' ),
// 'type' => 'string',
// 'description' => __( 'The actual log value' ),
// 'validation' => ''
// ],
'log_diffs' => [ // deprecated
'map' => 'meta',
'title' => __( 'Log differences', 'tainacan' ),
'description' => __( 'Differences between old and new versions of object', 'tainacan' )
@ -115,10 +105,27 @@ class Logs extends Repository {
'title' => __( 'Log collection relationship', 'tainacan' ),
'description' => __( 'The ID of the collection that this log is related to', 'tainacan' )
],
'item_id' => [
'object_id' => [
'map' => 'meta',
'title' => __( 'Log item relationship', 'tainacan' ),
'description' => __( 'The id of the item that this log is related to', 'tainacan' ),
'description' => __( 'The id of the object that this log is related to', 'tainacan' ),
],
'object_type' => [
'map' => 'meta',
'title' => __( 'Log item relationship', 'tainacan' ),
'description' => __( 'The type of the object that this log is related to', 'tainacan' ),
],
'old_value' => [
'map' => 'meta',
'title' => __( 'Old Value', 'tainacan' ),
],
'new_value' => [
'map' => 'meta',
'title' => __( 'New value', 'tainacan' ),
],
'action' => [
'map' => 'meta',
'title' => __( 'Action', 'tainacan' ),
]
] );
}
@ -219,6 +226,10 @@ class Logs extends Repository {
return $this->insert( $object );
}
/**
* Feth most recent log
* @return Entities\Log The most recent Log entity
*/
public function fetch_last() {
$args = [
'post_type' => Entities\Log::get_post_type(),
@ -232,196 +243,535 @@ class Logs extends Repository {
return array_pop( $logs );
}
public function prepare_attachment_log_before_insert( $post_ID ) {
/**
* Callback to generate log when attachments are added to any Tainacan entity
*/
public function insert_attachment( $post_ID ) {
$attachment = get_post( $post_ID );
$post = $attachment->post_parent;
if ( $post ) {
// was added attachment on a tainacan object
if ( $post ) { // attached to a post
$tainacan_post = Repository::get_entity_by_post( $post );
$entity = Repository::get_entity_by_post( $post );
if ( $tainacan_post ) {
// was added a normal attachment
if ( $entity ) { // attached to a tainacan entity
// get all attachments except the new
$old_attachments_objects = $tainacan_post->get_attachments( $post_ID );
$log = new Entities\Log();
// get all attachments
$new_attachments_objects = $tainacan_post->get_attachments();
$old_attachments = $this->prepare_attachments($old_attachments_objects);
$new_attachments = $this->prepare_attachments($new_attachments_objects);
$array_diff_with_index = array_map( 'unserialize',
array_diff_assoc( array_map( 'serialize', $new_attachments ), array_map( 'serialize', $old_attachments ) ) );
$diff['attachments'] = [
'new' => $new_attachments,
'old' => $old_attachments,
'diff_with_index' => $array_diff_with_index
];
$this->insert_log( $tainacan_post, $diff, true );
$collection_id = method_exists($entity, 'get_collection_id') ? $entity->get_collection_id() : 'default';
if ( $entity instanceof Entities\Collection ) {
$collection_id = $entity->get_id();
$log->set_title( sprintf( __( 'New file was attached to Collection "%s"', 'tainacan'), $entity->get_name() ) );
}
if ( $entity instanceof Entities\Item ) {
$log->set_item_id($entity->get_id());
$log->set_title( sprintf( __( 'New file was attached to Item "%s"', 'tainacan'), $entity->get_title() ) );
}
}
$object_type = get_class($entity);
$object_id = $entity->get_id();
$diff = [];
$log->set_collection_id($collection_id);
$log->set_object_type($object_type);
$log->set_object_id($object_id);
$log->set_action('new-attachment');
$title = __( sprintf('') , 'tainacan');
private function prepare_attachments($attachments) {
$attachments_prepared = [];
if ( is_array($attachments) ) {
foreach ( $attachments as $attachment ) {
$prepared = [
'id' => $attachment->ID,
'title' => $attachment->post_title,
'description' => $attachment->post_content,
'mime_type' => $attachment->post_mime_type,
'url' => $attachment->guid,
];
array_push( $attachments_prepared, $prepared );
$log->set_new_value($prepared);
if ( $log->validate() ) {
$this->insert($log);
}
}
}
return $attachments_prepared;
}
/**
* Insert a log when a new entity is inserted
*
* @param Entity $value
* @param array $diffs
* @param bool $is_update
*
* @param bool $is_delete
* @param bool $is_trash
*
* @return Entities\Log|bool new created log
* Callback to generate log when attachments attached to any Tainacan entity are deleted
*/
public function insert_log( $value, $diffs = [], $is_update = false, $is_delete = false, $is_trash = false ) {
$title = null;
$description = null;
public function pre_delete_attachment($attachment_id) {
$attachment_post = get_post($attachment_id);
$entity_post = get_post($attachment_post->post_parent);
if ( $entity_post ) {
$entity = Repository::get_entity_by_post( $entity_post );
if ( $entity ) {
$collection_id = method_exists($entity, 'get_collection_id') ? $entity->get_collection_id() : 'default';
$log = new Entities\Log();
if ( $entity instanceof Entities\Collection ) {
$collection_id = $entity->get_id();
$log->set_title( sprintf(__( 'File attached to Collection "%s" was removed', 'tainacan'), $entity->get_name() ) );
}
if ( $entity instanceof Entities\Item ) {
$log->set_item_id($entity->get_id());
$log->set_title( sprintf( __( 'File attached to Item "%s" was removed' , 'tainacan'), $entity->get_title() ) );
}
$object_type = get_class($entity);
$object_id = $entity->get_id();
$preapred = [
'id' => $attachment_id,
'title' => $attachment_post->post_title,
'description' => $attachment_post->post_content,
];
$log->set_collection_id($collection_id);
$log->set_object_type($object_type);
$log->set_object_id($object_id);
$log->set_old_value($preapred);
$log->set_action('delete-attachment');
$this->current_attachment_delete_log = $log;
}
}
}
/**
* Callback to generate log when attachments attached to any Tainacan entity are deleted
*/
public function delete_attachment($attachment_id) {
if ( isset($this->current_attachment_delete_log) && $this->current_attachment_delete_log instanceof Entities\Log ) {
$log = $this->current_attachment_delete_log;
$att = $log->get_old_value();
if ( is_array($att) && isset($att['id']) && $att['id'] == $attachment_id && $log->validate() ) {
$this->insert($log);
}
}
}
/**
* Compare two repository entities and sets the current_diff property to be used in the insert hook
*
* @param Entity $unsaved The new entity that is going to be saved
*
* @return void
*/
public function pre_insert_entity( Entities\Entity $unsaved ) {
if ( ! $unsaved->get_repository()->use_logs ) {
return;
}
if ( $unsaved instanceof Entities\Item_Metadata_Entity ) {
return $this->prepare_item_metadata_diff($unsaved);
}
if ( is_object( $value ) ) {
// do not log a log
if ( ( method_exists( $value, 'get_post_type' ) && $value->get_post_type() === 'tainacan-log' ) || $value->get_status() === 'auto-draft' ) {
return false;
if ( ( method_exists( $unsaved, 'get_post_type' ) && $unsaved->get_post_type() === 'tainacan-log' ) || $unsaved->get_status() === 'auto-draft' ) {
return;
}
if ( $value instanceof Entities\Metadatum ) {
$type = $value->get_metadata_type();
$creating = true;
if ( $type === 'Tainacan\Metadata_Types\Core_Title' || $type === 'Tainacan\Metadata_Types\Core_Description' ) {
return false;
$old = null;
if ( is_numeric( $unsaved->get_id() ) ) {
if ( $unsaved instanceof Entities\Term ) {
$old = $unsaved->get_repository()->fetch( $unsaved->get_id(), $unsaved->get_taxonomy() );
} else {
$old = $unsaved->get_repository()->fetch( $unsaved->get_id() );
}
}
$type = get_class( $value );
$class_name = explode( '\\', $type )[2];
$name = method_exists( $value, 'get_name' ) ? $value->get_name() :
( method_exists( $value, 'get_title' ) ? $value->get_title() : $value->get_metadatum()->get_name() );
if ( $old instanceof Entities\Entity ) {
if ( ! $name ) {
$name = $value->get_status();
if ( $old->get_status() !== 'auto-draft' ) {
$creating = false;
}
if ( $is_update ) {
// entity was delete
$title = $this->prepare_event_title( $value, $name, $class_name, 'updated' );
$description = $title;
} elseif ( $is_delete ) {
// entity was deleted
$title = $this->prepare_event_title( $value, $name, $class_name, 'deleted' );
$description = $title;
} elseif ( ! empty( $diffs ) ) {
// entity was created
$title = $this->prepare_event_title( $value, $name, $class_name, 'created' );
$description = $title;
} elseif ( $is_trash ) {
// entity was trashed
$title = $this->prepare_event_title( $value, $name, $class_name, 'trashed' );
$description = $title;
}
$title = apply_filters( 'tainacan-insert-log-message-title', $title, $type, $value );
$description = apply_filters( 'tainacan-insert-log-description', $description, $type, $value );
$diff = [
'old' => [],
'new' => []
];
$has_diff = false;
if ( $creating ) {
$diff['new'] = $unsaved->_toArray();
$has_diff = true;
} else {
$map = $unsaved->get_repository()->get_map();
foreach ( $map as $prop => $mapped ) {
if ( $old->get( $prop ) != $unsaved->get( $prop ) ) {
$diff['old'][$prop] = $old->get( $prop );
$diff['new'][$prop] = $unsaved->get( $prop );
$has_diff = true;
}
}
}
if ( !empty( $diffs ) || $is_delete || $is_trash) {
return Entities\Log::create( $title, $description, $value, $diffs );
$diff = apply_filters( 'tainacan-entity-diff', $diff, $unsaved, $old );
$this->current_diff = $has_diff ? $diff : false;
$this->current_action = $creating ? 'create' : 'update';
}
private function prepare_item_metadata_diff( Entities\Entity $unsaved ) {
$diff = [
'old' => [],
'new' => []
];
$old = new Entities\Item_Metadata_Entity($unsaved->get_item(), $unsaved->get_metadatum());
add_filter('tainacan-item-metadata-get-multivalue-separator', [$this, '__temporary_multivalue_separator']);
if ( $old instanceof Entities\Item_Metadata_Entity ) {
$diff['old'] = \explode($this->__temporary_multivalue_separator(''), $old->get_value_as_string());
}
$diff['new'] = \explode($this->__temporary_multivalue_separator(''), $unsaved->get_value_as_string());
remove_filter('tainacan-item-metadata-get-multivalue-separator', [$this, '__temporary_multivalue_separator']);
$diff = apply_filters( 'tainacan-entity-diff', $diff, $unsaved, $old );
$this->current_diff = $diff;
$this->current_action = 'update-metadata-value';
}
public function __temporary_multivalue_separator($sep) {
return '--xx--';
}
/**
* This will prepare the event title for objects
*
* @param $object
* @param $name
* @param $class_name
*
* @param $action_message
*
* @return string
* Callback to generate log when Tainacan entities are edited
*/
private function prepare_event_title( $object, $name, $class_name, $action_message ) {
public function insert_entity( Entities\Entity $entity ) {
// translators: 1=Object name, 2=Object type, 3=Action. e.g. The "Subject" taxonomy has been created
$title_format = __( '"%1$s" %2$s has been %3$s', 'tainacan' );
if ( $object instanceof Entities\Metadatum || $object instanceof Entities\Item || $object instanceof Entities\Filter ) {
$collection = $object->get_collection();
if ( $collection ) {
$parent = sprintf( __('(collection: %s)', 'tainacan'), $collection->get_name() );
} else {
$parent = __('(on repository level)', 'tainacan');
if ( ! $entity->get_repository()->use_logs ) {
return;
}
$title = sprintf( $title_format, $name, strtolower( $class_name ), $action_message );
$title .= ' ' . $parent . '.';
} elseif($object instanceof Entities\Item_Metadata_Entity) {
$title = sprintf(
$title_format,
$name,
__('item metadatum', 'tainacan'),
$action_message
) . ' ' . sprintf( __('(item: %s)', 'tainacan'), $object->get_item()->get_title() ) . '.';
} else {
$title = sprintf( $title_format, $name, strtolower( $class_name ), $action_message ) . '.';
if ( $entity instanceof Entities\Item_Metadata_Entity ) {
return $this->insert_item_metadata($entity);
}
// do not log a log
if ( ( method_exists( $entity, 'get_post_type' ) && $entity->get_post_type() === 'tainacan-log' ) || $entity->get_status() === 'auto-draft' ) {
return false;
}
$log = new Entities\Log();
$log->set_action($this->current_action);
$collection_id = method_exists($entity, 'get_collection_id') ? $entity->get_collection_id() : 'default';
$diff = $this->current_diff;
if (false === $diff) {
return;
}
if ( $entity instanceof Entities\Collection ) {
$collection_id = $entity->get_id();
if ($this->current_action == 'update') {
if (isset($diff['new']['metadata_order'])) {
$log->set_title( sprintf( __( 'Collection "%s" metadata order was updated', 'tainacan'), $entity->get_name() ) );
$log->set_action('update-metadata-order');
} elseif (isset($diff['new']['filters_order'])) {
$log->set_title( sprintf( __( 'Collection "%s" filters order was updated', 'tainacan'), $entity->get_name() ) );
$log->set_action('update-filters-order');
} else {
$log->set_title( sprintf( __( 'Collection "%s" was updated', 'tainacan'), $entity->get_name() ) );
}
} elseif ($this->current_action == 'create') {
$log->set_title( sprintf( __( 'Collection "%s" was created', 'tainacan'), $entity->get_name() ) );
}
} elseif ( $entity instanceof Entities\Item ) {
$log->set_item_id($entity->get_id());
if ($this->current_action == 'update') {
if (isset($diff['new']['document'])) {
$log->set_title( sprintf( __( 'Item "%s" document was updated', 'tainacan'), $entity->get_title() ) );
$log->set_action('update-document');
} elseif (isset($diff['new']['_thumbnail_id'])) {
$log->set_title( sprintf( __( 'Item "%s" thumbnail was updated', 'tainacan'), $entity->get_title() ) );
$log->set_action('update-thumbnail');
} else {
$log->set_title( sprintf( __( 'Item "%s" was updated', 'tainacan'), $entity->get_title() ) );
}
} elseif ($this->current_action == 'create') {
$log->set_title( sprintf( __( 'Item "%1$s" was created with the ID %2$s', 'tainacan'), $entity->get_title(), $entity->get_id() ) );
}
} elseif ( $entity instanceof Entities\Filter ) {
if ( 'default' == $collection_id ) {
if ($this->current_action == 'update') {
$log->set_title( sprintf( __( 'Filter "%1$s" was updated in repository level', 'tainacan'), $entity->get_name() ) );
} elseif ($this->current_action == 'create') {
$log->set_title( sprintf( __( 'Filter "%1$s" was added to the repository', 'tainacan'), $entity->get_name() ) );
}
} elseif ( is_numeric($collection_id) ) {
if ($this->current_action == 'update') {
$log->set_title( sprintf( __( 'Filter "%1$s" was updated in Collection "%2$s"', 'tainacan'), $entity->get_name(), $entity->get_collection()->get_name() ) );
} elseif ($this->current_action == 'create') {
$log->set_title( sprintf( __( 'Filter "%1$s" was added to Collection "%2$s"', 'tainacan'), $entity->get_name(), $entity->get_collection()->get_name() ) );
}
}
} elseif ( $entity instanceof Entities\Metadatum ) {
if ( 'default' == $collection_id ) {
if ($this->current_action == 'update') {
$log->set_title( sprintf( __( 'Metadatum "%s" was updated in repository level', 'tainacan'), $entity->get_name() ) );
} elseif ($this->current_action == 'create') {
$log->set_title( sprintf( __( 'Metadatum "%1$s" was added to the repository', 'tainacan'), $entity->get_name() ) );
}
} elseif ( is_numeric($collection_id) ) {
if ($this->current_action == 'update') {
$log->set_title( sprintf( __( 'Metadatum "%s" was updated in Collection "%2$s"', 'tainacan'), $entity->get_name(), $entity->get_collection()->get_name() ) );
} elseif ($this->current_action == 'create') {
$log->set_title( sprintf( __( 'Metadatum "%1$s" was added to Collection "%2$s"', 'tainacan'), $entity->get_name(), $entity->get_collection()->get_name() ) );
}
}
} elseif ( $entity instanceof Entities\Taxonomy ) {
if ($this->current_action == 'update') {
$log->set_title( sprintf( __( 'Taxonomy "%s" was updated', 'tainacan'), $entity->get_name() ) );
} elseif ($this->current_action == 'create') {
$log->set_title( sprintf( __( 'Taxonomy "%1$s" was created', 'tainacan'), $entity->get_name() ) );
}
} elseif ( $entity instanceof Entities\Term ) {
$taxonomy = Taxonomies::get_instance()->fetch_by_db_identifier($entity->get_taxonomy());
$tax_name = '';
if ($taxonomy instanceof Entities\Taxonomy) {
$tax_name = $taxonomy->get_name();
}
if ($this->current_action == 'update') {
$log->set_title( sprintf( __( 'Term "%1$s" was updated in "%2$s" taxonomy', 'tainacan'), $entity->get_name(), $tax_name ) );
} elseif ($this->current_action == 'create') {
$log->set_title( sprintf( __( 'Term "%1$s" was added to "%2$s" taxonomy', 'tainacan'), $entity->get_name(), $tax_name ) );
}
}
$object_type = get_class($entity);
$object_id = $entity->get_id();
$log->set_collection_id($collection_id);
$log->set_object_type($object_type);
$log->set_object_id($object_id);
$log->set_old_value($diff['old']);
$log->set_new_value($diff['new']);
if ( $log->validate() ) {
$this->insert($log);
}
}
public function pre_delete_entity( Entities\Entity $entity, bool $permanent) {
if ( ! $entity->get_repository()->use_logs ) {
return;
}
// do not log a log
if ( ( method_exists( $entity, 'get_post_type' ) && $entity->get_post_type() === 'tainacan-log' ) || $entity->get_status() === 'auto-draft' ) {
return false;
}
$this->current_deleting_entity = $entity->_toArray();
$this->current_action = $permanent ? 'delete' : 'trash';
}
public function delete_entity( Entities\Entity $entity, bool $permanent) {
if ( ! $entity->get_repository()->use_logs ) {
return;
}
// do not log a log
if ( ( method_exists( $entity, 'get_post_type' ) && $entity->get_post_type() === 'tainacan-log' ) || $entity->get_status() === 'auto-draft' ) {
return false;
}
$log = new Entities\Log();
$collection_id = method_exists($entity, 'get_collection_id') ? $entity->get_collection_id() : 'default';
if ( $entity instanceof Entities\Collection ) {
$collection_id = $entity->get_id();
if ($this->current_action == 'delete') {
$log->set_title( sprintf( __( 'Collection "%s" was permanently deleted', 'tainacan'), $entity->get_name() ) );
} elseif ($this->current_action == 'trash') {
$log->set_title( sprintf( __( 'Collection "%s" was moved to trash', 'tainacan'), $entity->get_name() ) );
}
} elseif ( $entity instanceof Entities\Item ) {
$log->set_item_id($entity->get_id());
if ($this->current_action == 'delete') {
$log->set_title( sprintf( __( 'Item "%1$s" (ID %2$s) was updated', 'tainacan'), $entity->get_title(), $entity->get_id() ) );
} elseif ($this->current_action == 'trash') {
$log->set_title( sprintf( __( 'Item "%1$s" (ID %2$s) was moved to trash', 'tainacan'), $entity->get_title(), $entity->get_id() ) );
}
} elseif ( $entity instanceof Entities\Filter ) {
if ( 'default' == $collection_id ) {
if ($this->current_action == 'delete') {
$log->set_title( sprintf( __( 'Filter "%s" was permanently deleted from the repository', 'tainacan'), $entity->get_name() ) );
} elseif ($this->current_action == 'trash') {
$log->set_title( sprintf( __( 'Repository Filter "%1$s" was moved to trash', 'tainacan'), $entity->get_name() ) );
}
} elseif ( is_numeric($collection_id) ) {
if ($this->current_action == 'delete') {
$log->set_title( sprintf( __( 'Filter "%1$s" was permanently deleted from Collection "%2$s"', 'tainacan'), $entity->get_name(), $entity->get_collection()->get_name() ) );
} elseif ($this->current_action == 'trash') {
$log->set_title( sprintf( __( 'Filter "%1$s" was moved to trash in Collection "%2$s"', 'tainacan'), $entity->get_name(), $entity->get_collection()->get_name() ) );
}
}
} elseif ( $entity instanceof Entities\Metadatum ) {
if ( 'default' == $collection_id ) {
if ($this->current_action == 'delete') {
$log->set_title( sprintf( __( 'Metadatum "%s" was permanently deleted from the repository', 'tainacan'), $entity->get_name() ) );
} elseif ($this->current_action == 'trash') {
$log->set_title( sprintf( __( 'Repository Metadatum "%1$s" was moved to trash', 'tainacan'), $entity->get_name() ) );
}
} elseif ( is_numeric($collection_id) ) {
if ($this->current_action == 'delete') {
$log->set_title( sprintf( __( 'Metadatum "%1$s" was permanently deleted from Collection "%2$s"', 'tainacan'), $entity->get_name(), $entity->get_collection()->get_name() ) );
} elseif ($this->current_action == 'trash') {
$log->set_title( sprintf( __( 'Metadatum "%1$s" was moved to trash in Collection "%2$s"', 'tainacan'), $entity->get_name(), $entity->get_collection()->get_name() ) );
}
}
} elseif ( $entity instanceof Entities\Taxonomy ) {
if ($this->current_action == 'delete') {
$log->set_title( sprintf( __( 'Taxonomy "%s" was permanently deleted', 'tainacan'), $entity->get_name() ) );
} elseif ($this->current_action == 'trash') {
$log->set_title( sprintf( __( 'Taxonomy "%1$s" was moved to trash', 'tainacan'), $entity->get_name() ) );
}
} elseif ( $entity instanceof Entities\Term ) {
$taxonomy = Taxonomies::get_instance()->fetch_by_db_identifier($entity->get_taxonomy());
$tax_name = '';
if ($taxonomy instanceof Entities\Taxonomy) {
$tax_name = $taxonomy->get_name();
}
if ($this->current_action == 'delete') {
$log->set_title( sprintf( __( 'Term "%1$s" was permanently deleted from "%2$s" taxonomy', 'tainacan'), $entity->get_name(), $tax_name ) );
} elseif ($this->current_action == 'trash') {
$log->set_title( sprintf( __( 'Term "%1$s" was moved to trash in "%2$s" taxonomy', 'tainacan'), $entity->get_name(), $tax_name ) );
}
}
$object_type = get_class($entity);
$object_id = $entity->get_id();
$diff = $this->current_diff;
$log->set_collection_id($collection_id);
$log->set_object_type($object_type);
$log->set_object_id($object_id);
$log->set_action($this->current_action);
if ( $permanent ) {
$log->set_old_value( $this->current_deleting_entity );
} else {
$log->set_old_value( ['status' => $entity->get_status()] );
$log->set_new_value( ['status' => 'trash'] );
}
if ( $log->validate() ) {
$this->insert($log);
}
}
private function insert_item_metadata( Entities\Item_Metadata_Entity $entity ) {
$log = new Entities\Log();
$item_id = $entity->get_item()->get_id();
$collection_id = $entity->get_item()->get_collection_id();
$object_type = get_class($entity);
$object_id = $entity->get_metadatum()->get_id();
$diff = $this->current_diff;
$log->set_collection_id($collection_id);
$log->set_object_type($object_type);
$log->set_object_id($object_id);
$log->set_item_id($item_id);
$log->set_old_value($diff['old']);
$log->set_new_value($diff['new']);
$log->set_action($this->current_action);
$meta_name = $entity->get_metadatum()->get_name();
$item_title = $entity->get_item()->get_title();
$title = sprintf( __( 'Value for %1$s metadatum was updated in item "%2$s"', 'tainacan' ), $meta_name, $item_title );
$log->set_title($title);
if ( $log->validate() ) {
$this->insert($log);
}
}
public function filter_log_title($title) {
if (defined('TAINACAN_DOING_IMPORT') && true === TAINACAN_DOING_IMPORT) {
$_title = __('Importer', 'tainacan');
$title .= " ($_title)";
}
return $title;
}
/**
*
* @param Entities\Log $log
*
* @return Entities\Entity|boolean return insert/update valeu or false
* @throws \Exception
*/
public function approve( $log ) {
$log = self::get_entity_by_post( $log );
if ( $log->get_status() == 'pending' ) {
/** @var Entity $value * */
$value = $log->get_value();
$value->set_status( 'publish' ); // TODO check if publish the entity on approve
$repository = self::get_repository( $value );
if ( $value->validate() ) {
return $repository->insert( $value );
}
}
return false;
}
}

View File

@ -129,20 +129,8 @@ abstract class Repository {
$diffs = [];
if ( $this->use_logs ) {
if ( $obj->get_id() ) {
$old = $obj->get_repository()->fetch( $obj->get_id() );
if ( method_exists( $old, 'get_status' ) && $old->get_status() === 'auto-draft' ) {
$is_update = false;
} else {
$is_update = true;
}
$diffs = $this->diff( $old, $obj );
}
}
do_action( 'tainacan-pre-insert', $obj );
do_action( 'tainacan-pre-insert-' . $obj->get_post_type(), $obj );
$map = $this->get_map();
@ -186,11 +174,6 @@ abstract class Repository {
}
}
// TODO: Logs for header image insert and update
if ( $this->use_logs ) {
$this->logs_repository->insert_log( $obj, $diffs, $is_update );
}
do_action( 'tainacan-insert', $obj, $diffs, $is_update );
do_action( 'tainacan-insert-' . $obj->get_post_type(), $obj );
@ -624,6 +607,10 @@ abstract class Repository {
* @return mixed|Entity @see https://developer.wordpress.org/reference/functions/wp_delete_post/
*/
public function delete( Entities\Entity $entity, $permanent = true ) {
do_action( 'tainacan-pre-delete', $entity, $permanent );
do_action( 'tainacan-pre-delete-' . $entity->get_post_type(), $entity, $permanent );
if ($permanent === true) {
$return = wp_delete_post( $entity->get_id(), $permanent );
} elseif ($permanent === false) {
@ -632,7 +619,6 @@ abstract class Repository {
if ( $return instanceof \WP_Post && $this->use_logs ) {
$this->logs_repository->insert_log( $entity, [], false, false, true );
do_action( 'tainacan-deleted', $entity, $permanent );
do_action( 'tainacan-deleted-' . $entity->get_post_type(), $entity, $permanent );
@ -804,88 +790,6 @@ abstract class Repository {
return $temp_array;
}
/**
* Compare two repository entities
*
* @param Entity|integer|\WP_Post $old default ($which = 0) to self compare with stored entity
* @param Entity|integer|\WP_Post $new
*
* @return array List of diff values
* @throws \Exception
*/
public function diff( $old = 0, $new ) {
$old_entity = null;
if ( $old === 0 || is_array( $old ) && count( $old ) == 0 ) { // self diff or other entity?
$id = $new->get_id();
if ( ! empty( $id ) ) { // there is a repository entity?
$old_entity = $this->get_entity_by_post( $new->WP_Post->ID );
} else {
$entity_type = get_class( $new );
$old_entity = new $entity_type; // there is no saved entity, let compare with a new empty one
}
} else {
if ( $old->get_status() === 'auto-draft' ) {
$entity_type = get_class( $new );
$old_entity = new $entity_type;
} else {
$old_entity = $old;
}
}
$new_entity = $new;
$map = $this->get_map();
$diff = [];
foreach ( $map as $prop => $mapped ) {
// I can't verify differences on item, because it attributes are added when item is a auto-draft
if ( $old_entity->get_mapped_property( $prop ) != $new_entity->get_mapped_property( $prop ) ) {
if ( $mapped['map'] === 'meta_multi' || ( $mapped['map'] === 'meta' && is_array( $new_entity->get_mapped_property( $prop ) ) ) ) {
// Array of diffs with index of diff in new array
$new_v = $new_entity->get_mapped_property( $prop );
$old_v = $old_entity->get_mapped_property( $prop );
$old_v = ! is_array( $old_v ) && empty( $old_v ) && ! is_string( $old_v ) ? array() : ( ! is_string( $old_v ) ? $old_v : [ $old_v ] );
$array_diff_with_index = array_map( 'unserialize',
array_diff_assoc( array_map( 'serialize', $new_v ), array_map( 'serialize', $old_v ) ) );
if ( ! empty( $array_diff_with_index ) ) {
$diff[ $prop ] = [
'new' => $new_entity->get_mapped_property( $prop ),
'old' => $old_entity->get_mapped_property( $prop ),
'diff_with_index' => $array_diff_with_index,
];
}
} elseif ( $mapped['map'] !== 'post_modified' ) {
$new_as_array = explode( ' ', $new_entity->get_mapped_property( $prop ) );
$old_as_array = explode( ' ', $old_entity->get_mapped_property( $prop ) );
// Array of diffs with index of diff in new array
$array_diff_with_index = array_diff_assoc( $new_as_array, $old_as_array );
$diff[ $prop ] = [
'new' => $new_as_array,
'old' => $old_entity->get_mapped_property( $prop ),
'diff_with_index' => $array_diff_with_index,
];
}
}
}
unset( $diff['id'], $diff['collection_id'], $diff['author_id'], $diff['creation_date'], $diff['_thumbnail_id'] );
$diff = apply_filters( 'tainacan-entity-diff', $diff, $new, $old );
return $diff;
}
/**
* Inserts or update thumbnail for items and collections and return an array
* with old thumbnail and new thumbnail

View File

@ -208,7 +208,7 @@ class Taxonomies extends Repository {
* @param array $args WP_Query args plus disabled_metadata
* @param string $output The desired output format (@see \Tainacan\Repositories\Repository::fetch_output() for possible values)
*
* @return array Entities\Metadatum
* @return array Entities\Taxonomy
* @throws \Exception
*/
public function fetch_by_collection( Entities\Collection $collection, $args = [], $output = null ) {
@ -241,6 +241,22 @@ class Taxonomies extends Repository {
}
/**
* fetch taxonomies by DB Identifier
*
* @param string $db_identifier The db Identifier of the taxonomy. This is the internal WordPress taxonomy slug, something like tnc_123_tax
*
* @return Entities\Taxonomy|Array The entity when found. An empty array when nothing was found
* @throws \Exception
*/
public function fetch_by_db_identifier($db_identifier) {
$id = $this->get_id_by_db_identifier($db_identifier);
if ($id) {
return $this->fetch( (int) $id );
}
return [];
}
public function update( $object, $new_values = null ) {
return $this->insert( $object );
}

View File

@ -117,15 +117,8 @@ class Terms extends Repository {
throw new \Exception( 'Entities must be validated before you can save them' );
}
$is_update = false;
$diffs = [];
if ( $term->get_id() && $this->use_logs) {
$is_update = true;
$old = $this->fetch( $term->get_id(), $term->get_taxonomy() );
$diffs = $this->diff( $old, $term );
}
do_action( 'tainacan-pre-insert', $term );
do_action( 'tainacan-pre-insert-term', $term );
// First iterate through the native post properties
$map = $this->get_map();
@ -170,16 +163,12 @@ class Terms extends Repository {
}
}
if($this->use_logs){
// TODO: Log header image updates
$this->logs_repository->insert_log( $term, $diffs, $is_update );
}
$new_entity = new Entities\Term( $term_saved['term_id'], $term->get_taxonomy() );
do_action( 'tainacan-insert', $new_entity );
do_action( 'tainacan-insert-term', $new_entity );
do_action( 'tainacan-insert', $term, $diffs, $is_update );
do_action( 'tainacan-insert-term', $term );
return new Entities\Term( $term_saved['term_id'], $term->get_taxonomy() );
return $new_entity;
}
// TODO: Is this workaround ok to avoid getting htmlentities ?
@ -246,8 +235,8 @@ class Terms extends Repository {
}
return $return;
} elseif ( is_numeric( $args ) && ! empty( $cpt ) && ! is_array( $cpt ) ) { // if an id is passed taxonomy cannot be an array
$wp_term = get_term_by( 'id', $args, $cpt );
} elseif ( is_numeric( $args ) ) {
$wp_term = get_term( (int) $args, $cpt );
$tainacan_term = new Entities\Term( $wp_term );
return $tainacan_term;
} else {
@ -261,18 +250,23 @@ class Terms extends Repository {
/**
* @param Entities\Term $term
* @param bool $permanent this parameter is not used by Terms repository
* @param bool $permanent this parameter is not used by Terms repository. Delete is always permanent
*
* @return bool|int|mixed|\WP_Error
*/
public function delete( Entities\Entity $term, $permanent = true ) {
$deleted = $term;
$permanent = true; // there is no such option for terms
do_action( 'tainacan-pre-delete', $deleted, $permanent );
do_action( 'tainacan-pre-delete-term', $deleted, $permanent );
$return = wp_delete_term( $term->get_id(), $term->get_taxonomy() );
if ( $deleted && $this->use_logs ) {
$this->logs_repository->insert_log( $deleted, [], false, true );
do_action( 'tainacan-deleted', $deleted );
do_action( 'tainacan-deleted-term', $deleted );
if ( $deleted ) {
do_action( 'tainacan-deleted', $deleted, $permanent );
do_action( 'tainacan-deleted-term', $deleted, $permanent );
}
return $return;

View File

@ -31,6 +31,8 @@ class Background_Importer extends Background_Process {
$data = $batch->data;
$key = $batch->key;
define('TAINACAN_DOING_IMPORT', true);
$className = $data['class_name'];
if (class_exists($className)) {
$object = new $className($data);

View File

@ -604,9 +604,9 @@ class CSV extends Importer {
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$Tainacan_Items->disable_logs();
$Tainacan_Metadata->disable_logs();
$Tainacan_Item_Metadata->disable_logs();
// $Tainacan_Items->disable_logs();
// $Tainacan_Metadata->disable_logs();
// $Tainacan_Item_Metadata->disable_logs();
$itemMetadataArray = [];
@ -622,6 +622,8 @@ class CSV extends Importer {
if ( $item->get_id() == $this->get_transient('item_id') ) {
$this->add_log('item will be updated ID:' . $item->get_id() );
$updating_item = true;
// When creating a new item, disable log for each metadata to speed things up
$Tainacan_Item_Metadata->disable_logs();
} else {
$this->add_log('item with ID ' . $item->get_id() . ' not found. Unable to update. Creating a new one.' );
}

View File

@ -159,6 +159,7 @@ abstract class Importer {
}
}
}
public function _to_Array($short = false) {

View File

@ -1,9 +1,28 @@
import axios from '../../../axios/axios'
import axios from '../../../axios/axios';
import qs from 'qs';
export const fetchActivities = ({ commit }, { page, activitiesPerPage, search, searchDates} ) => {
let endpoint = `/logs?paged=${page}&perpage=${activitiesPerPage}&context=edit&orderby=id&order=desc`;
if (search != undefined && search != '')
endpoint += `&search=${search}`;
if (searchDates && searchDates[0] != null && searchDates[1] != null) {
let dateQuery = {
datequery: [
{
'after': searchDates[0],
'before': searchDates[1],
'inclusive': true
}
]
};
endpoint += '&' + qs.stringify(dateQuery);
}
export const fetchActivities = ({ commit }, { page, activitiesPerPage } ) => {
return new Promise((resolve, reject) => {
axios.tainacan.get(`/logs?paged=${page}&perpage=${activitiesPerPage}&context=edit&orderby=id&order=desc`)
axios.tainacan.get(endpoint)
.then(res => {
let activities = res.data;
@ -18,9 +37,28 @@ export const fetchActivities = ({ commit }, { page, activitiesPerPage } ) => {
});
};
export const fetchCollectionActivities = ({ commit }, { page, activitiesPerPage, collectionId }) => {
export const fetchCollectionActivities = ({ commit }, { page, activitiesPerPage, collectionId, search, searchDates }) => {
let endpoint = `/collection/${collectionId}/logs?paged=${page}&perpage=${activitiesPerPage}&context=edit&orderby=id&order=desc`;
if (search != undefined && search != '')
endpoint += `&search=${search}`;
if (searchDates && searchDates[0] != null && searchDates[1] != null) {
let dateQuery = {
datequery: [
{
'after': searchDates[0],
'before': searchDates[1],
'inclusive': true
}
]
};
endpoint += '&' + qs.stringify(dateQuery);
}
return new Promise((resolve, reject) => {
axios.tainacan.get(`/collection/${collectionId}/logs?paged=${page}&perpage=${activitiesPerPage}&context=edit&orderby=id&order=desc`)
axios.tainacan.get(endpoint)
.then(res => {
let activities = res.data;
@ -35,9 +73,28 @@ export const fetchCollectionActivities = ({ commit }, { page, activitiesPerPage,
});
};
export const fetchItemActivities = ({ commit }, { page, activitiesPerPage, itemId }) => {
export const fetchItemActivities = ({ commit }, { page, activitiesPerPage, itemId, search, searchDates }) => {
let endpoint = `/item/${itemId}/logs?paged=${page}&perpage=${activitiesPerPage}&context=edit&orderby=id&order=desc`;
if (search != undefined && search != '')
endpoint += `&search=${search}`;
if (searchDates && searchDates[0] != null && searchDates[1] != null) {
let dateQuery = {
datequery: [
{
'after': searchDates[0],
'before': searchDates[1],
'inclusive': true
}
]
};
endpoint += '&' + qs.stringify(dateQuery);
}
return new Promise((resolve, reject) => {
axios.tainacan.get(`/item/${itemId}/logs?paged=${page}&perpage=${activitiesPerPage}&context=edit&orderby=id&order=desc`)
axios.tainacan.get(endpoint)
.then(res => {
let activities = res.data;
@ -53,6 +110,7 @@ export const fetchItemActivities = ({ commit }, { page, activitiesPerPage, itemI
};
export const fetchActivity = ({ commit }, activityId) => {
commit('clearActivity');
return new Promise((resolve, reject) => {
axios.tainacan.get(`/logs/${activityId}?context=edit`)
.then(res => {

View File

@ -9,3 +9,7 @@ export const setActivity = (state, activity) => {
export const setActivityTitle = (state, eventTitle) => {
state.eventTitle = eventTitle;
};
export const clearActivity = (state) => {
state.activity = {};
};

View File

@ -192,10 +192,10 @@ export const fetchRepositoryCollectionFilters = ({ dispatch, commit } ) => {
axios.all(promises).then((results) => {
for (let resp of results) {
let repositoryFilters = resp.filter.filter((filter) => {
return (filter.collection_id == 'default' || filter.collection_id == 'filter_in_repository')
return (filter.collection_id == 'default')
});
let collectionFilters = resp.filter.filter((filter) => {
return (filter.collection_id != 'default' && filter.collection_id != 'filter_in_repository')
return (filter.collection_id != 'default')
});
commit('setRepositoryCollectionFilters', { collectionName: resp.collectionId, repositoryCollectionFilters: collectionFilters });
commit('setRepositoryCollectionFilters', { collectionName: undefined, repositoryCollectionFilters: repositoryFilters });
@ -240,10 +240,10 @@ export const fetchTaxonomyFilters = ({ dispatch, commit }, taxonomyId ) => {
axios.tainacan.get(endpoint)
.then((resp) => {
let repositoryFilters = resp.data.filter((filter) => {
return (filter.collection_id == 'default' || filter.collection_id == 'filter_in_repository') && filter.metadatum.metadata_type_object.options.taxonomy_id != taxonomyId
return (filter.collection_id == 'default') && filter.metadatum.metadata_type_object.options.taxonomy_id != taxonomyId
});
let collectionFilters = resp.data.filter((filter) => {
return (filter.collection_id != 'default' && filter.collection_id != 'filter_in_repository') && filter.metadatum.metadata_type_object.options.taxonomy_id != taxonomyId
return (filter.collection_id != 'default') && filter.metadatum.metadata_type_object.options.taxonomy_id != taxonomyId
});
commit('setTaxonomyFiltersForCollection', { collectionName: collectionId, taxonomyFilters: collectionFilters });
commit('setTaxonomyFiltersForCollection', { collectionName: undefined, taxonomyFilters: repositoryFilters });

View File

@ -348,6 +348,17 @@ class Migrations {
}
static function update_repository_filters_meta() {
global $wpdb;
$wpdb->query( "UPDATE $wpdb->postmeta SET meta_value = 'default' WHERE
post_id IN (
SELECT ID FROM $wpdb->posts WHERE post_type = 'tainacan-filter'
) AND meta_key = 'collection_id' AND meta_value = 'filter_in_repository'"
);
}
static function update_relationship_metadata_search_option() {
global $wpdb;

View File

@ -0,0 +1,59 @@
<?php
namespace Tainacan\Tests;
/**
* @group api_item_meta
*/
class TAINACAN_REST_Item_Metadata_Controller extends TAINACAN_UnitApiTestCase {
protected $item;
protected $collection;
protected $metadatum;
protected function create_meta_requirements() {
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'testeItemMetadata',
'description' => 'No description',
),
true,
true
);
$type = $this->tainacan_metadatum_factory->create_metadatum('text');
$metadatum = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'teste_metadado',
'description' => 'descricao',
'collection' => $collection,
'metadata_type' => $type,
'accept_suggestion' => true
),
true,
true
);
$item = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item_teste_metadado',
'description' => 'adasdasdsa',
'collection' => $collection
),
true,
true
);
$this->collection = $collection;
$this->item = $item;
$this->metadatum = $metadatum;
return ['collection' => $collection, 'item' => $item, 'metadatum' => $metadatum];
}
}
?>

21
tests/_test-logs.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace Tainacan\Tests;
use Tainacan\Entities\Collection;
use Tainacan\Entities\Log;
/**
* Class TestCollections
*
* @package Test_Tainacan
*/
/**
* Sample test case.
*/
class Logs extends TAINACAN_UnitTestCase {
}

View File

@ -321,7 +321,7 @@ class TAINACAN_REST_Terms_Controller extends TAINACAN_UnitApiTestCase {
$data = $response_create->get_data();
$this->assertEquals('filter_in_repository', $data['collection_id']);
$this->assertEquals('default', $data['collection_id']);
#### CREATE A FILTER IN COLLECTION WITHOUT METADATUM ASSOCIATION ####

View File

@ -1,188 +0,0 @@
<?php
namespace Tainacan\Tests;
/**
* @group api_item_meta
*/
class TAINACAN_REST_Item_Metadata_Controller extends TAINACAN_UnitApiTestCase {
protected $item;
protected $collection;
protected $metadatum;
protected function create_meta_requirements() {
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'testeItemMetadata',
'description' => 'No description',
),
true,
true
);
$type = $this->tainacan_metadatum_factory->create_metadatum('text');
$metadatum = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'teste_metadado',
'description' => 'descricao',
'collection' => $collection,
'metadata_type' => $type,
'accept_suggestion' => true
),
true,
true
);
$item = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item_teste_metadado',
'description' => 'adasdasdsa',
'collection' => $collection
),
true,
true
);
$this->collection = $collection;
$this->item = $item;
$this->metadatum = $metadatum;
return ['collection' => $collection, 'item' => $item, 'metadatum' => $metadatum];
}
public function test_create_suggestion_item_metadata_in_a_collection(){
extract($this->create_meta_requirements());
$item__metadata_json = json_encode([
'values' => 'TestValues_metadado',
]);
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $item->get_id() . '/metadata/' . $metadatum->get_id() );
$request->set_body($item__metadata_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals($item->get_id() , $data['item']['id']);
$this->assertEquals('TestValues_metadado', $data['value']);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata/'. $metadatum->get_id() );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals( 'TestValues_metadado', $data['value'] );
// Test Suggestion
$new_user = $this->factory()->user->create(array( 'role' => 'subscriber' ));
wp_set_current_user($new_user);
$item__metadata_json = json_encode([
'values' => 'TestValuesSuggestion_metadado',
]);
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $item->get_id() . '/metadata/' . $metadatum->get_id() );
$request->set_body($item__metadata_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals( 'pending', $data['status'] );
$Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance();
$query = $Tainacan_Logs->fetch(['post_status' => 'pending']);
$log = false;
while ($query->have_posts()) {
$query->the_post();
$post = get_post();
$log = $Tainacan_Logs->get_entity_by_post($post);
}
$pending = $log->get_value();
$this->assertEquals('TestValuesSuggestion_metadado', $pending->get_value());
wp_set_current_user($this->user_id);
$request = new \WP_REST_Request('POST', $this->namespace . '/logs/' . $log->get_id() . '/approve' );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata/'. $metadatum->get_id() );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals( 'TestValuesSuggestion_metadado', $data['value'] );
}
function test_create_anonymous_suggestion_item_metadata_in_a_collection() {
extract($this->create_meta_requirements());
$item__metadata_json = json_encode([
'values' => 'TestValues_metadado',
]);
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $item->get_id() . '/metadata/' . $metadatum->get_id() );
$request->set_body($item__metadata_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
// Test Anonymous Suggestion
wp_logout();
wp_set_current_user(0);
$this->assertEquals(0, get_current_user_id());
$item__metadata_json = json_encode([
'values' => 'TestValuesAnonymousSuggestion_metadado',
]);
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $item->get_id() . '/metadata/' . $metadatum->get_id() );
$request->set_body($item__metadata_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals( 'pending', $data['status'] );
$Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance();
$query = $Tainacan_Logs->fetch(['post_status' => 'pending']);
$log = false;
while ($query->have_posts()) {
$query->the_post();
$post = get_post();
$log = $Tainacan_Logs->get_entity_by_post($post);
}
$pending = $log->get_value();
$this->assertEquals('TestValuesAnonymousSuggestion_metadado', $pending->get_value());
wp_set_current_user($this->user_id);
$request = new \WP_REST_Request('POST', $this->namespace . '/logs/' . $log->get_id() . '/approve' );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata/'. $metadatum->get_id() );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals( 'TestValuesAnonymousSuggestion_metadado', $data['value'] );
}
}
?>

View File

@ -72,7 +72,6 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_UnitApiTestCase {
$this->assertEquals(200, $response->get_status());
$data = $response->get_data()['items'];
$items_titles = [$data[0]['title'], $data[1]['title']];
$this->assertContains($item1->get_title(), $items_titles);
@ -155,7 +154,11 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_UnitApiTestCase {
}
public function test_update_item(){
$collection = $this->tainacan_entity_factory->create_entity('collection', '', true);
$collection = $this->tainacan_entity_factory->create_entity('collection', array(
'name' => 'Agile',
'description' => 'Agile methods',
'status' => 'publish'
), true);
$item = $this->tainacan_entity_factory->create_entity(
'item',
@ -163,6 +166,7 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_UnitApiTestCase {
'title' => 'SCRUM e PMBOK',
'description' => 'Unidos no Gerenciamento de Projetos',
'collection' => $collection,
'status' => 'publish'
),
true
);
@ -181,7 +185,6 @@ class TAINACAN_REST_Items_Controller extends TAINACAN_UnitApiTestCase {
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertNotEquals($item->get_title(), $data['title']);
$this->assertEquals('SCRUM e XP', $data['title']);
}

View File

@ -318,34 +318,6 @@ class Collections extends TAINACAN_UnitTestCase {
$this->assertTrue(has_action('init', array($Tainacan_Collections, 'register_post_type')) !== false, 'Collections Init is not registred!');
}
/**
* @group diff
*/
function test_diff() {
$x = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'testeDiff',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
'moderators_ids' => [1,2,3]
),
true
);
$x->set_name('OtherValue');
$x->set_description('testeDiff2');
$x->set_moderators_ids([3,4,5]);
$diff = $x->diff();
$this->assertEquals(3, count($diff));
$this->assertEquals($diff['name']['new'][0], 'OtherValue');
$this->assertEquals($diff['name']['old'], 'testeDiff');
$this->assertEquals($diff['description']['new'][0], 'testeDiff2');
$this->assertEquals($diff['description']['old'], 'adasdasdsa');
$this->assertEquals([1 => 4, 2 => 5, 0 => 3], $diff['moderators_ids']['diff_with_index']);
}
function test_create_child_collection() {

View File

@ -178,7 +178,7 @@ class Filters extends TAINACAN_UnitTestCase {
'filter',
array(
'name' => 'filter default',
'collection_id' => 'filter_in_repository',
'collection_id' => 'default',
'filter_type' => 'Tainacan\Filter_Types\Selectbox',
'metadatum_id' => $meta_repo->get_id(),
'status' => 'publish'

View File

@ -1,72 +0,0 @@
<?php
namespace Tainacan\Tests;
use Tainacan\Entities\Collection;
use Tainacan\Entities\Log;
/**
* Class TestCollections
*
* @package Test_Tainacan
*/
/**
* Sample test case.
*/
class Logs extends TAINACAN_UnitTestCase {
/**
* Teste da insercao de um log simples apenas se criar o dado bruto
*/
function test_add() {
$Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance();
$log = $this->tainacan_entity_factory->create_entity(
'log',
array(
'title' => 'blame someone',
'description' => 'someone did that'
),
true
);
$user_id = get_current_user_id();
$blog_id = get_current_blog_id();
//retorna a taxonomia
$test = $Tainacan_Logs->fetch( $log->get_id() );
$this->assertEquals( 'blame someone', $test->get_title() );
$this->assertEquals( 'someone did that', $test->get_description() );
$this->assertEquals( $user_id, $test->get_user_id() );
$this->assertEquals( $blog_id, $test->get_blog_id() );
}
public function test_log_diff() {
$Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance();
$Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
$filter = $this->tainacan_entity_factory->create_entity(
'filter',
array(
'name' => 'No name',
),
true
);
// Modify filter name
$filter->set_name( 'With name' );
$Tainacan_Filters->update( $filter );
$log = $Tainacan_Logs->fetch_last();
$diff = $log->get_log_diffs();
$this->assertEquals( 'With name', "{$diff['name']['new'][0]} {$diff['name']['new'][1]}" );
$this->assertEquals( 'No name', $diff['name']['old'] );
$this->assertEquals( 'With', $diff['name']['diff_with_index'][0] );
}
}