Merge branch 'develop' of https://github.com/tainacan/tainacan into develop
This commit is contained in:
commit
76e29c30ea
|
@ -0,0 +1,72 @@
|
||||||
|
sudo: false
|
||||||
|
language: php
|
||||||
|
php:
|
||||||
|
- 7.1
|
||||||
|
- 7.2
|
||||||
|
- 5.6
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
fast_finish: true
|
||||||
|
addons:
|
||||||
|
- ssh_know_hosts:
|
||||||
|
- "$ssh_host"
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- mysql-5.7-trusty
|
||||||
|
- phpunit-6.1
|
||||||
|
packages:
|
||||||
|
- sshpass
|
||||||
|
- mysql-server
|
||||||
|
- mysql-client
|
||||||
|
services:
|
||||||
|
- mysql
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get install sshpass
|
||||||
|
- sudo service mysql restart
|
||||||
|
- mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
|
||||||
|
install:
|
||||||
|
- echo -e "Install"
|
||||||
|
- sudo mv ./tests/bootstrap-config-sample.php ./tests/bootstrap-config.php
|
||||||
|
- sudo ./tests/bin/install-wp-tests.sh test travis "" /tmp/wordpress localhost latest
|
||||||
|
true
|
||||||
|
- composer install
|
||||||
|
- sudo mkdir /tmp/wordpress/wordpress-test/wp-content/uploads
|
||||||
|
script: phpunit
|
||||||
|
before_deploy:
|
||||||
|
- echo "Seção executada antes do deploy!"
|
||||||
|
- openssl aes-256-cbc -K $encrypted_cb93ef43fcd2_key -iv $encrypted_cb93ef43fcd2_iv
|
||||||
|
-in deploy_rsa.enc -out /tmp/deploy_rsa -d
|
||||||
|
- eval "$(ssh-agent -s)"
|
||||||
|
- chmod 600 /tmp/deploy_rsa
|
||||||
|
- ssh-add /tmp/deploy_rsa
|
||||||
|
- echo -e "Host $ssh_host\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||||
|
- ssh-add -l
|
||||||
|
deploy:
|
||||||
|
- provider: script
|
||||||
|
script: ssh $ssh_user@$ssh_host $script_deploy_tainacan
|
||||||
|
skip_cleanup: true
|
||||||
|
on:
|
||||||
|
branch: develop
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- vendor
|
||||||
|
- composer
|
||||||
|
notifications:
|
||||||
|
slack:
|
||||||
|
rooms:
|
||||||
|
secure: WjgA4OIad0/Ai+x1TUd7KShXpaJco9E/MfI6DWJFnBUF5JLKOxymTGbR82wspmnEwzXGWn++co1wNJh20pWobaIToL/2OpBd7xo5MHglNobH4cidmSIDPOQM8ItqBneRjayhXtfShRqQDNCk1D3d5KDUacXXeCX+GLdRuwdc/YuG7Zh3y1KrF6l10cwD/5JOJECwwMbqeLOezvzGi8ITL6pqnEEeNTb0Zr+K2Ru91RBOars4TLK3f5CmX4XxA4oQSMsrHKzTO2OZLua5CRwcBwKmtSqr0Z/W+RrXu2TLxvHYJ39t9uwssI3HmGoB/uNcahBTcE0Vk/phi3nfFO8KUGNqp3xLgUsF/xlb+WiIip2xOf9jq+XNGWwIVB2vWqiQppm58h57LgDNTF21XJOtfVPEyf9Em+VSfNgACq47u4kktgqgZ47xNEBZuv1s3as8BcgdQH78hF+qguhhHJH6RgyHt+GYAq2uRLF8z3IM8hfKpb5mA9jD3UfW3pXEtKF9K+XqtNycX8KxJ2ldEJrMguaqW3sUHSLBo+r71OqldHeuwIfyIGIROTym11GWH56rIXxd51nJuVDWMvTg7bwcjN/d61LdfsaOAgqAYSUPlJjjp67GHZP/vson3uPr//NgnAJ/4gtjwReB7IX8oBLhB5s8lU6dnfnsLbY3Rt+THNA=
|
||||||
|
on_sucess: always
|
||||||
|
on_failure: always
|
||||||
|
email:
|
||||||
|
on_success: never
|
||||||
|
on_failure: always
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- secure: LnUpxgHL/Qgpbg20mRErlnwb8tvNs6f7uPRe9c82UuMP69uDZeD3K5GNzL6u0Y+C/zNHk7tCnUszDC7FtQAij6qi72HHW2zz4zVJ+DFI3b+hx7+rSKsjtbnJChTbknSu3rW+yHYRTIUZJQ/Tg6thDLKzU0a4VRb+ickDpRYLyP+Cf4+xs7rwAhjiboMNIGXahrCpnbhctmOhRgZaHvfnPB9prRs5lOCCBQqSwMmjEo7OJeCCUjfpU5xq3EjUEzwjzzBlSf3240PS/LOBFr2iGF30VT9LDTb1iUZU1gTcaxaK+/EjKLG/wtcH8TOaLJpsksbnMkSTrG3ICblXl1G4Itu8IHzLgOmWoiWIVXZ4y17aYyj/y7YZtX+fjB6qs9RG5ZnSpHkSDEni8CCC8Ltf9jVSkLEust/bNLgkd02hJ4xtVxOaoBYEh3hcylJ/co8BTDdbNyT3BwrFc4f2jfRh5DYzyrKaTG5IJAT2BfyjD/BsxBE3EgIuJFja1zVJKMcuCmogDiHi6sb0zhF+LbLy0nXqvysTrMEYbDppVYQloz3BKb2v2m/jc89G7v8AjnvwTUgj64PUj+p10ngfIA+FHPILLtd/fNm0zRIRDqSfE7rpGZo9EoZ9jq0wVSmy0DK8kFTX+9RFW8xYmFnTgB3beKWqdK9CAqXEeeD3ABejXTc=
|
||||||
|
- secure: ZgQILlaSklEldQIISTfQC+0vhutWYs3nWzQP6bRluHmzb0PSz/7VqoFfzj7mi3AEtvsNIfDGv1AL8NUdqj9ZKBhgcFN178UcM87ObXIhpkZ43yIcNEHGQXBu0WN9Hn2kpj8sTWUFkzDUfLznShR8FDWwyxHHdH5TAMYJ8ZvLaDWZBAKJ0V+PYJASoI9CKVT16rx+K87MSavqvgLHsRticLgK/V/KVi5CMr/4J2WSeUpgzxKPLKP2yoTspJXbcUWuZcbXR+hp/MIvFJVYw7kK6wpixAzAuw6evrYwfOxLjZ5P2pNFrpMtBfONYKFpWxZyiPeUO8kBAV5R7XpzUUzfxRgu9Ca+6VYm8mNfHck4p7NLK+IjHLi1CrL3YYu8Ck1O01ah2i1ZIEaGL+NVRdrTHNOWZfWok3Wsv4UyLsgAeM4/K6dExauUqgVE/cwm/mwQ9ycoAoqfwVteHBmb7N+2nhlQwP1K1RAArS0ldm16aOD/eYcQ9kd5IQjRHr+QnMmhm7XRLJwxxL/Wpss7DNG4zWfEFNS9yYfDa8q0CRLT68sSjd5egnGyjYrW5dMSzFSu8G6CR/NvXTExlElxmilehDoLrGqRmLedW/jlbPQmNf6T+fVOE/r5vn//wMpk/e7rc0ivXh0YSDfyZ/3I052Uqingxl0ruLsoM6zIQW3b91U=
|
||||||
|
- secure: uUM5BXTWfh6jWqBdbu7sUrVVo4dUMNdorPaB6DNo0xOcjK/+b6lI41oQODmLKz48in0N0aWU+DH4gf3kkyhd/4ebPozHP5R/31ygYiNUzPFttZteV1rzCDaK/kwR8bH1p0hYibSeuqQgLt+VA7MD87x1/V1HrxZ+BPwYcrt8zNOb1ufqanu8t2URhyng5ZySOuBtXoDi9mR3KHX/V6DI1IybuAroV6LZm6d3PKpyD4GQtj48uw2IETQqMYXkHwYKPgIBLeXVDqMV8JP3MQ5WppheL7RBwHuClIAEPK47WEcnVqWkHssH3E3whzpIOo99R6EqRfVDAGwZAu2+SDuqFu5QGDfAF99ZSbh/m96lj9/drWK+0KOHOtEqhEq5FycOkLuHREIdLIg9uGqXLaGY+noAU7jXi70Uk3v4zrDxUocIdPrMaTutrE0pUPacCgnHtkTOkpJr7PHq2Zry8kMU39IRJQ3nIVcxSoUlWv9Xd+RjMw833RdZ1m5HVzUT+zE2jr8jhJgiNb/amQpH8pYcqI+NDqk8RFn9O0fhWYJmePtgDK0++9VAdBs8A4lmiFbkB+qotdZLemFhQObNOQsK/a3YoDgvjGfnvMXyGLdEFoT962mmnMteBq/mCcSEnRqLSA5gifzoJyeLRXKmVpoRAwrtjn5u8Qa+a8BQKCpDyno=
|
||||||
|
- secure: TxMSWrKRGiDamfCdmpfVJMG9fpXrlgGhS6Pbm7iO3eMMS6v+ZF5Qo7RyGYPsJvspKuncGpuRynoKff8jWsouYDqyMFZvtmG9EyJI2GYvy7K4E2HRRrZeNZHviP0tKq++0L5VLiY3pr9uUZYbmjKTk2k5V7ddd2EVK6AIqh/7dLmf9FPZ7HE+QuEQiaijBZ/mvBW+ntZHfZoyv/yWW5zPcA6vxAdtMa1iXhv6ByGFd+odCblq6HmBqDlaASDoXrrTSc0bkXeX44tqt+OMDhwsEqtzLlI5x1WYnYt5lkFuGjTn+WG/PLmrJxbq1c4MXU1cgcaiuRP8Y/Gq1XoffbFa9KZ/jfx0c9dxwRIedJrctrGC8jSSmlM1C+p9QFGWZUhF3b0WgRvP8NYUhQ0ToV3rE4XeApElHd27FYibDkWz72cpq6EiehJoQLFLyKpWcu7gtgjMUbGIllF2k6+oV7jzpgRNktzz5gWH2i1Vj5//Wyq1Md5NJ+sBspTmTcw9s09W2ghG/9bzksS5XtpOFfYVIqkeFbBK0lcGufDNoVSci4kTs12U/OMLcXaEUymHpKCS1UWCj/nRjxUosBBQ+WQzAJixEijTs8t0WKZZ2eDZhTOnpa50WV4DDO/EZHaQ7sgm98Y/V9gwvyLTOifjT2eXDNYXdH90RBGbDoUueyavqag=
|
||||||
|
- secure: ZZBechMeYwtzFe8dsMDQ3QPLUvZ2P5+abcTZbODMRmOomm5PixOr6EVJhVaUYnEtqgc4AaNnzVGmNrfoyEZC9Kza4hyEfABHPPcMDOUoC8v5HVpX08nLvWs6e5MdFCNeqWlJpTUR1ZVpYjXuIvaVVO9aT1N7ZAZBYPEaPotxPOt1+viJmWOUFpqhap/9VPkSn16DUiz9vQcJQe7PfxclxQkyhFlIhO0LRE//sR42ED1P3/efIRoAdfMSgISuLgQhZZYJ0wrh2aVz5YjRLfq80rQEynLFfCvSVEWhde3ZRGgX7oWo7LRfXF/0t4g/52QhfpWUvFw1fvljhzd/o1xUY6j2u3OS6Atx87QOvdj9a0D33UjWyOEXumUVupoSN5jnFnb41lKSoYwmx7rEEYGtYCBIzBkZfqOiKn0KYn1yIQbW0g6ptlC5C3o0wZchdCTaWnvNd2m6lj+a2j30b88F815qe0V7H9GxzUknccLfG/v/stBOFpYv1zd4bVgcmARHNwWORN6U3C+r9A3AoJkhLRedfsfmcftnxol55Okpz6Jn0z8/KVtuZ6FNlN3qfP5RLE6vP2y1s5fu/EWnsbNkP5JdCWKrRF9rryu3CURpci9f4zYcghuIRMfuZ9muQhdS7MYLJhwldy6lzPYg2l66laRgPkxeTHAamXHalhQXi60=
|
||||||
|
- secure: VMRxLl42yXCGRsmogIoYb31jzE9dyCpmlyB2fM+VsNNp/WWp1IB5QhhmH5klxw7KG16+Mhz7E9k99v+CmOyMVWmse3l9JXUoImdUNue5csgiMziHXU6A0zXv3EZVI0MfWilBoFOlc91c0n9h1jlUJ9VSBIaac+VqM8Icpw/w2ASha4XujJ02ahnYItmz9WVG2rG7mKYpc9DDHi2zbR+LyNLuX4tvi1CQtkpRiIFbs5eX+vIwQ2bFG1vpbbsiFkFPVGRlfh4DQaNo0Bam08BfsmK4TkYRiGxXZYTBM1QWJKdnzTZOnZ8uaiKCAGxC+5VsWuuqFfn9qPfx/7S43NGwG9aJSglkRZ9S4eKodMjCg+oGosq2dkGasll7owrk1vY1/rBjJodg+Y0q5uOXYfjT/Jmq0c/u0uQewUSdG6mSMEpmbSg43cAeA/9xruM0sVelBzH5zgvzQjUF6yTsN0E3XVwxmS6l1YesnfYXmGnJ1w5vQJMbLaN1FyPoRw0AsaGGqQooL4FEwb+vu299J9x61U4GxKJrJd16mRWItu0Rj4oZ79zdElTRcjvGQz4j1qelDDfxufst9hIqkSjIEzsBPZMIp/49FJfKwgsuB2fl8L3q4XnqPG4AXRRsb25JEMPQYEpvk31kVmtCGadhAKgLrjZ2Kd6amyZ37pt2oASilGA=
|
||||||
|
- secure: C+qQ9H2aTpZAjHBEW4LcRODxdozEwerA8CF1bQZ2sJCXY0wlP9tikaaNWrCBWGv9/v7X5qIwORXJwGyEAxg331FsJNvQ7i+rNSbna5NlHozWChUQvjPe+fWpCPdAEKeAF+JyDLKRbsWo2SqiaYDsnTXD5BaancOCGqkpEDZrm7HdUL091arG8CJVjUG2OaEo0aNsnuw7Z9NVTw5zD9lmGBlpKlTwXXfjzNg1Y5ThHkfxsCoYWa8rfL+wdec6ZghJFZ6ITZbYKBPbXYIUyJO1dboJi0+EhAnL9rD1NmcK2ERz8d99HqKhzEI/KoHCtOe+czOBhi5/OMe2lza1tL+z3uFF4TS86Qdk7JARegdHdxTPlztcagTd70wUwJ1POMBRnrVdFhnXvWDX87lk0RGvGUlCTsh+lMwZBM4UdMH96Eb+mwECe5qeWE8vGkPEtny6sTKhJvEhHmHmVNL/tYdqXsEdgfSOSHrhXfvesUMvr62/KlA9mFTtAzShom+4Jpx+1OlLdNDHyRmODoRhDJnuHRCOCjXzks8W12Hbg5ej7KnqLO0ymlGQumGoVjWzOHKwdNuItN1mEGRA/p0+nxS2tSAyg9rJF4spFRugGa1yapDzj7bqUfq8oCa4qzIbuiNU22Y8SQMdYJxvHBhq4wLcRX9g7u1uNEtKyykb5+nrKug=
|
||||||
|
- secure: YQEb1NAiHbgkiaHGJ6FHxMb7CYy44uszfqyC2Yj98ueuZDFJFIJqchUe9k2H3CdayU0i7MhCEk0LL4hSZpXRhyyFs6AxWh82ISPrBaraCyd5x51EoKPeVmTW1MTLjl467HX357Do41JsooMkGX8llpaAzJP5mY7fJmx91Cnpg5dQbAeSWhwSM16yfYHHpQXvoGmTlcj89hoJ7LLTMEg6o+CgGlYnx5LB/vvWxHNiMNVB+IJEMo7MopQUVkVqTEJ+k8x0i2tBdwLNCoMl79xrsYETsSRzn85zuD/wqfY0yfvEwYsKD1YtkjJW14/y4mFFHCyW+/igORknuBRF1qRZEOHeTMiDmNOsA2yi1RXjNIeUpOctCNV29KDAyqkOfQwlKMzezBGoVKRsxd3oWZpjNjnqgQ7lEx5CwQKN5pSxMmd1pWZTkY+Ci9b+VrBvshhdPwBKsjZjS8jDHlX0uT6OHPN17PFziCtKRfh+gukSLJJcxRz9H/4F6NLpFJzx4/UsFLW45XY5BXwucYgUyk+oXeQDlzSXVpAuE2KDOaHWg12jlnWptTq7rHfKE0N61JOgolThCun5i+0L6eydaPNswqUtbB/WlDdkbpDMaUFR/HFDFNkTiJyPpTeYHdsqwq57hqI/D2Otkc28wbVHodYZyxiaLe9gozmD5IYS8Sf9tdM=
|
|
@ -1,3 +1,5 @@
|
||||||
|
[![Waffle.io - Columns and their card count](https://badge.waffle.io/tainacan/tainacan.svg?columns=In%20Progress)](https://waffle.io/tainacan/tainacan)
|
||||||
|
|
||||||
# Tainacan
|
# Tainacan
|
||||||
|
|
||||||
** This is the development repository of a new version of Tainacan. If you are looking for the current stable version, please visit http://github.com/medialab-ufg/tainacan. **
|
** This is the development repository of a new version of Tainacan. If you are looking for the current stable version, please visit http://github.com/medialab-ufg/tainacan. **
|
||||||
|
|
Binary file not shown.
|
@ -23,7 +23,7 @@ class Admin {
|
||||||
add_filter( 'admin_body_class', array( &$this, 'admin_body_class' ) );
|
add_filter( 'admin_body_class', array( &$this, 'admin_body_class' ) );
|
||||||
|
|
||||||
add_action( 'init', array( &$this, 'register_user_meta' ) );
|
add_action( 'init', array( &$this, 'register_user_meta' ) );
|
||||||
add_action( 'after_setup_theme', array( &$this, 'load_icon_font'));
|
add_action( 'after_setup_theme', array( &$this, 'load_theme_files'));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,14 +58,15 @@ class Admin {
|
||||||
return $style;
|
return $style;
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_icon_font() {
|
function load_theme_files() {
|
||||||
add_action( 'wp_enqueue_scripts', array(&$this, 'add_material_design_icon_css') );
|
add_action( 'wp_enqueue_scripts', array(&$this, 'add_theme_files') );
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_material_design_icon_css() {
|
function add_theme_files() {
|
||||||
global $TAINACAN_BASE_URL;
|
global $TAINACAN_BASE_URL;
|
||||||
|
|
||||||
wp_enqueue_style( 'style', $TAINACAN_BASE_URL . '/assets/css/fonts/materialdesignicons.css' );
|
wp_enqueue_style( 'style', $TAINACAN_BASE_URL . '/assets/css/fonts/materialdesignicons.css' );
|
||||||
|
wp_enqueue_script('underscore', includes_url('js') . '/underscore.min.js' );
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_admin_css() {
|
function add_admin_css() {
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="columns is-multiline tnc-advanced-search-container">
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="searchField in totalSearchMetadata"
|
||||||
|
:key="searchField"
|
||||||
|
class="field column is-12 tainacan-form">
|
||||||
|
|
||||||
|
<b-field
|
||||||
|
class="columns"
|
||||||
|
grouped>
|
||||||
|
<b-field class="column">
|
||||||
|
<b-select
|
||||||
|
@input.native="addToAdvancedSearchQuery($event)">
|
||||||
|
<option
|
||||||
|
v-for="metadata in metadataList"
|
||||||
|
v-if="metadata.enabled"
|
||||||
|
:value="metadata.id"
|
||||||
|
:key="metadata.id"
|
||||||
|
>{{ metadata.name }}</option>
|
||||||
|
</b-select>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field class="column is-two-thirds">
|
||||||
|
<b-input
|
||||||
|
@input.native="addValueToAdvancedSearchQuery($event)"/>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field class="column">
|
||||||
|
<b-select
|
||||||
|
@input.native="addToAdvancedSearchQuery($event)">
|
||||||
|
<option
|
||||||
|
v-for="(opt, key) in compare"
|
||||||
|
:value="key"
|
||||||
|
:key="key"
|
||||||
|
>{{ opt }}</option>
|
||||||
|
</b-select>
|
||||||
|
</b-field>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
:style="{'padding-left': '25px !important'}"
|
||||||
|
class="field column is-12">
|
||||||
|
|
||||||
|
<div class="is-inline">
|
||||||
|
<b-icon
|
||||||
|
icon="plus-circle"
|
||||||
|
size="is-small"
|
||||||
|
type="is-secondary"/>
|
||||||
|
<a
|
||||||
|
@click="addSearchMetadata"
|
||||||
|
class="is-secondary is-small">
|
||||||
|
{{ $i18n.get('add_more_one_search_field') }}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="field is-grouped is-pulled-right">
|
||||||
|
<p class="control">
|
||||||
|
<button
|
||||||
|
@click="clearSearch"
|
||||||
|
class="button is-outlined">{{ $i18n.get('clear_search') }}</button>
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<button
|
||||||
|
@click="searchAdvanced"
|
||||||
|
class="button is-secondary">{{ $i18n.get('search') }}</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "AdvancedSearch",
|
||||||
|
props: {
|
||||||
|
metadataList: Array,
|
||||||
|
isRepositoryLevel: false,
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
compare: {'=':'Igual', '!=':'Diferente', 'IN':'Contém', 'NOT IN':'Não Contém'},
|
||||||
|
totalSearchMetadata: 1,
|
||||||
|
advancedSearchQuery: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addSearchMetadata(){
|
||||||
|
this.totalSearchMetadata++;
|
||||||
|
},
|
||||||
|
clearSearch(){
|
||||||
|
this.totalSearchMetadata = 1;
|
||||||
|
},
|
||||||
|
addValueToAdvancedSearchQuery: _.debounce(($event) => {
|
||||||
|
console.log($event);
|
||||||
|
}, 900),
|
||||||
|
searchAdvanced(){
|
||||||
|
|
||||||
|
},
|
||||||
|
addToAdvancedSearchQuery($event){
|
||||||
|
console.log($event);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
@import '../../scss/_variables.scss';
|
||||||
|
|
||||||
|
.tnc-advanced-search-container {
|
||||||
|
padding-top: 47px;
|
||||||
|
padding-right: $page-side-padding;
|
||||||
|
padding-left: $page-side-padding;
|
||||||
|
padding-bottom: 47px;
|
||||||
|
|
||||||
|
.column {
|
||||||
|
padding: 0 0.3rem 0.3rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control {
|
||||||
|
.select{
|
||||||
|
width: 100% !important;
|
||||||
|
select{
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -140,6 +140,7 @@
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
import TermsList from '../lists/terms-list.vue'
|
import TermsList from '../lists/terms-list.vue'
|
||||||
import htmlToJSON from 'html-to-json';
|
import htmlToJSON from 'html-to-json';
|
||||||
|
import CustomDialog from '../other/custom-dialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CategoryEditionForm',
|
name: 'CategoryEditionForm',
|
||||||
|
@ -194,17 +195,20 @@
|
||||||
formNotSaved = true;
|
formNotSaved = true;
|
||||||
|
|
||||||
if (formNotSaved) {
|
if (formNotSaved) {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.$i18n.get('info_warning_category_not_saved'),
|
parent: this,
|
||||||
|
component: CustomDialog,
|
||||||
|
props: {
|
||||||
|
icon: 'alert',
|
||||||
|
title: this.$i18n.get('label_warning'),
|
||||||
|
message: this.$i18n.get('info_warning_category_not_saved'),
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
next();
|
next();
|
||||||
},
|
}
|
||||||
cancelText: this.$i18n.get('cancel'),
|
}
|
||||||
confirmText: this.$i18n.get('continue'),
|
});
|
||||||
type: 'is-secondary'
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
next()
|
next();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -301,6 +301,7 @@
|
||||||
class="control"
|
class="control"
|
||||||
custom>
|
custom>
|
||||||
<b-checkbox
|
<b-checkbox
|
||||||
|
v-if="registeredViewModes[viewMode] != undefined"
|
||||||
@input="updateViewModeslist(viewMode)"
|
@input="updateViewModeslist(viewMode)"
|
||||||
:value="checkIfViewModeEnabled(viewMode)">
|
:value="checkIfViewModeEnabled(viewMode)">
|
||||||
{{ registeredViewModes[viewMode].label }}
|
{{ registeredViewModes[viewMode].label }}
|
||||||
|
@ -326,6 +327,7 @@
|
||||||
@focus="clearErrors('default_view_mode')">
|
@focus="clearErrors('default_view_mode')">
|
||||||
<option
|
<option
|
||||||
v-for="(viewMode, index) of form.enabled_view_modes"
|
v-for="(viewMode, index) of form.enabled_view_modes"
|
||||||
|
v-if="registeredViewModes[viewMode] != undefined"
|
||||||
:key="index"
|
:key="index"
|
||||||
:value="viewMode">{{ registeredViewModes[viewMode].label }}
|
:value="viewMode">{{ registeredViewModes[viewMode].label }}
|
||||||
</option>
|
</option>
|
||||||
|
@ -408,6 +410,8 @@ export default {
|
||||||
editFormErrors: {},
|
editFormErrors: {},
|
||||||
formErrorMessage: '',
|
formErrorMessage: '',
|
||||||
isNewCollection: false,
|
isNewCollection: false,
|
||||||
|
isMapped: false,
|
||||||
|
mapper: false,
|
||||||
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
|
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
|
||||||
headerPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_rectangle.png',
|
headerPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_rectangle.png',
|
||||||
isFetchingModerators: false,
|
isFetchingModerators: false,
|
||||||
|
@ -492,7 +496,7 @@ export default {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
// Creates draft Collection
|
// Creates draft Collection
|
||||||
let data = { name: '', description: '', status: 'auto-draft'};
|
let data = { name: '', description: '', status: 'auto-draft', mapper: (this.isMapped && this.mapper != false ? this.mapper : false ) };
|
||||||
this.sendCollection(data).then(res => {
|
this.sendCollection(data).then(res => {
|
||||||
|
|
||||||
this.collectionId = res.id;
|
this.collectionId = res.id;
|
||||||
|
@ -715,6 +719,15 @@ export default {
|
||||||
|
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
var tmppath = this.$route.fullPath.split("/");
|
||||||
|
var mapper = tmppath.pop();
|
||||||
|
if(tmppath.pop() == 'new') {
|
||||||
|
this.isNewCollection = true;
|
||||||
|
this.isMapped = true;
|
||||||
|
this.mapper = mapper;
|
||||||
|
this.createNewCollection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
:title="$i18n.getHelperTitle('items', 'status')"
|
:title="$i18n.getHelperTitle('items', 'status')"
|
||||||
:message="$i18n.getHelperMessage('items', 'status')"/>
|
:message="$i18n.getHelperMessage('items', 'status')"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-box section-status">
|
<div class="section-status">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<!-- <div class="block">
|
<!-- <div class="block">
|
||||||
<b-radio
|
<b-radio
|
||||||
|
@ -336,6 +336,7 @@ import { mapActions, mapGetters } from 'vuex';
|
||||||
import { eventBus } from '../../../js/event-bus-web-components.js'
|
import { eventBus } from '../../../js/event-bus-web-components.js'
|
||||||
import wpMediaFrames from '../../js/wp-media-frames';
|
import wpMediaFrames from '../../js/wp-media-frames';
|
||||||
import FileItem from '../other/file-item.vue';
|
import FileItem from '../other/file-item.vue';
|
||||||
|
import CustomDialog from '../other/custom-dialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ItemEditionForm',
|
name: 'ItemEditionForm',
|
||||||
|
@ -675,15 +676,18 @@ export default {
|
||||||
},
|
},
|
||||||
beforeRouteLeave ( to, from, next ) {
|
beforeRouteLeave ( to, from, next ) {
|
||||||
if (this.item.status == 'auto-draft') {
|
if (this.item.status == 'auto-draft') {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.$i18n.get('info_warning_item_not_saved'),
|
parent: this,
|
||||||
|
component: CustomDialog,
|
||||||
|
props: {
|
||||||
|
icon: 'alert',
|
||||||
|
title: this.$i18n.get('label_warning'),
|
||||||
|
message: this.$i18n.get('info_warning_item_not_saved'),
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
cancelText: this.$i18n.get('cancel'),
|
}
|
||||||
confirmText: this.$i18n.get('continue'),
|
});
|
||||||
type: 'is-secondary'
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
@ -803,7 +807,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.section-status{
|
.section-status{
|
||||||
width: 174px;
|
padding: 16px 0;
|
||||||
}
|
}
|
||||||
.section-thumbnail {
|
.section-thumbnail {
|
||||||
width: 174px;
|
width: 174px;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
@click="headerImageMediaFrame.openFrame($event)">
|
@click="headerImageMediaFrame.openFrame($event)">
|
||||||
<b-icon icon="pencil"/>
|
<b-icon icon="pencil"/>
|
||||||
</a>
|
</a>
|
||||||
<figure class="image is-128x128">
|
<figure class="image">
|
||||||
<span
|
<span
|
||||||
v-if="editForm.header_image === undefined || editForm.header_image === false"
|
v-if="editForm.header_image === undefined || editForm.header_image === false"
|
||||||
class="image-placeholder">{{ $i18n.get('label_empty_header_image') }}</span>
|
class="image-placeholder">{{ $i18n.get('label_empty_header_image') }}</span>
|
||||||
|
@ -29,18 +29,22 @@
|
||||||
<div class="thumbnail-buttons-row">
|
<div class="thumbnail-buttons-row">
|
||||||
<a
|
<a
|
||||||
id="button-delete"
|
id="button-delete"
|
||||||
:aria-label="$i18n.get('label_button_delete_header_image')"
|
:aria-label="$i18n.get('label_button_delete_thumb')"
|
||||||
@click="deleteHeaderImage()">
|
@click="deleteThumbnail()">
|
||||||
<b-icon icon="delete"/>
|
<b-icon
|
||||||
|
type="is-gray"
|
||||||
|
icon="delete" />
|
||||||
|
<span class="text">{{ $i18n.get('remove') }} </span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<a
|
<br>
|
||||||
v-if="editForm.url != undefined && editForm.url!= ''"
|
|
||||||
class="button is-secondary"
|
|
||||||
:href="editForm.url">
|
|
||||||
{{ $i18n.get('see') + ' ' + $i18n.get('term') }}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<a
|
||||||
|
v-if="editForm.url != undefined && editForm.url!= ''"
|
||||||
|
class="button is-secondary"
|
||||||
|
:href="editForm.url">
|
||||||
|
{{ $i18n.get('see') + ' ' + $i18n.get('term') }}
|
||||||
|
</a>
|
||||||
</b-field>
|
</b-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -229,15 +233,22 @@
|
||||||
|
|
||||||
@import "../../scss/_variables.scss";
|
@import "../../scss/_variables.scss";
|
||||||
|
|
||||||
|
.column {
|
||||||
|
padding: 0;
|
||||||
|
&.is-narrow {
|
||||||
|
padding-right: 42px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
padding: 1.0em 2.0em;
|
padding: 2.0rem 2rem 1rem 2rem;
|
||||||
border-top: 1px solid $draggable-border-color;
|
border-top: 1px solid $draggable-border-color;
|
||||||
border-bottom: 1px solid $draggable-border-color;
|
border-bottom: 1px solid $draggable-border-color;
|
||||||
margin-top: 1.0em;
|
margin-top: 1.0em;
|
||||||
|
|
||||||
.thumbnail-field {
|
.thumbnail-field {
|
||||||
max-height: 128px;
|
max-height: 128px;
|
||||||
margin-bottom: 96px;
|
margin-bottom: 66px;
|
||||||
margin-top: -20px;
|
margin-top: -20px;
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
@ -245,12 +256,14 @@
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
position: absolute;
|
position: relative;
|
||||||
|
width: 128px;
|
||||||
}
|
}
|
||||||
.image-placeholder {
|
.image-placeholder {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
top: 24px;
|
||||||
bottom: 50%;
|
bottom: 50%;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -273,18 +286,19 @@
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.thumbnail-buttons-row {
|
.thumbnail-buttons-row {
|
||||||
display: none;
|
display: inline-block;
|
||||||
}
|
padding: 8px 0px;
|
||||||
&:hover {
|
border-radius: 0px 0px 0px 4px;
|
||||||
.thumbnail-buttons-row {
|
font-size: 14px;
|
||||||
display: inline-block;
|
a { color: $tainacan-input-color; }
|
||||||
|
.text {
|
||||||
|
top: -3px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -128px;
|
}
|
||||||
background-color: rgba(255, 255, 255, 0.9);
|
i.mdi-24px.mdi-set, i.mdi-24px.mdi::before {
|
||||||
padding: 2px 8px;
|
font-size: 20px;
|
||||||
border-radius: 0px 0px 0px 4px;
|
|
||||||
left: 88px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex'
|
import { mapActions } from 'vuex';
|
||||||
|
import CustomDialog from '../other/custom-dialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CategoriesList',
|
name: 'CategoriesList',
|
||||||
|
@ -179,64 +180,76 @@
|
||||||
this.selectedCategories.splice(i, 1, !this.allCategoriesOnPageSelected);
|
this.selectedCategories.splice(i, 1, !this.allCategoriesOnPageSelected);
|
||||||
},
|
},
|
||||||
deleteOneCategory(categoryId) {
|
deleteOneCategory(categoryId) {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.$i18n.get('info_warning_category_delete'),
|
parent: this,
|
||||||
onConfirm: () => {
|
component: CustomDialog,
|
||||||
this.deleteCategory(categoryId)
|
props: {
|
||||||
.then(() => {
|
icon: 'alert',
|
||||||
// this.$toast.open({
|
title: this.$i18n.get('label_warning'),
|
||||||
// duration: 3000,
|
message: this.$i18n.get('info_warning_category_delete'),
|
||||||
// message: this.$i18n.get('info_category_deleted'),
|
onConfirm: () => {
|
||||||
// position: 'is-bottom',
|
this.deleteCategory(categoryId)
|
||||||
// type: 'is-secondary',
|
.then(() => {
|
||||||
// queue: true
|
// this.$toast.open({
|
||||||
// });
|
// duration: 3000,
|
||||||
for (let i = 0; i < this.selectedCategories.length; i++) {
|
// message: this.$i18n.get('info_category_deleted'),
|
||||||
if (this.selectedCategories[i].id === this.categoryId)
|
// position: 'is-bottom',
|
||||||
this.selectedCategories.splice(i, 1);
|
// type: 'is-secondary',
|
||||||
}
|
// queue: true
|
||||||
})
|
// });
|
||||||
.catch(() => {
|
for (let i = 0; i < this.selectedCategories.length; i++) {
|
||||||
// this.$toast.open({
|
if (this.selectedCategories[i].id === this.categoryId)
|
||||||
// duration: 3000,
|
this.selectedCategories.splice(i, 1);
|
||||||
// message: this.$i18n.get('info_error_deleting_category'),
|
}
|
||||||
// position: 'is-bottom',
|
})
|
||||||
// type: 'is-danger',
|
.catch(() => {
|
||||||
// queue: true
|
|
||||||
// });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deleteSelectedCategories() {
|
|
||||||
this.$dialog.confirm({
|
|
||||||
message: this.$i18n.get('info_warning_selected_categories_delete'),
|
|
||||||
onConfirm: () => {
|
|
||||||
|
|
||||||
for (let i = 0; i < this.categories.length; i++) {
|
|
||||||
if (this.selectedCategories[i]) {
|
|
||||||
this.deleteCategory(this.categories[i].id)
|
|
||||||
.then(() => {
|
|
||||||
// this.loadCategories();
|
|
||||||
// this.$toast.open({
|
|
||||||
// duration: 3000,
|
|
||||||
// message: this.$i18n.get('info_category_deleted'),
|
|
||||||
// position: 'is-bottom',
|
|
||||||
// type: 'is-secondary',
|
|
||||||
// queue: false
|
|
||||||
// })
|
|
||||||
}).catch(() => {
|
|
||||||
// this.$toast.open({
|
// this.$toast.open({
|
||||||
// duration: 3000,
|
// duration: 3000,
|
||||||
// message: this.$i18n.get('info_error_deleting_category'),
|
// message: this.$i18n.get('info_error_deleting_category'),
|
||||||
// position: 'is-bottom',
|
// position: 'is-bottom',
|
||||||
// type: 'is-danger',
|
// type: 'is-danger',
|
||||||
// queue: false
|
// queue: true
|
||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.allCategoriesOnPageSelected = false;
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteSelectedCategories() {
|
||||||
|
this.$modal.open({
|
||||||
|
parent: this,
|
||||||
|
component: CustomDialog,
|
||||||
|
props: {
|
||||||
|
icon: 'alert',
|
||||||
|
title: this.$i18n.get('label_warning'),
|
||||||
|
message: this.$i18n.get('info_warning_selected_categories_delete'),
|
||||||
|
onConfirm: () => {
|
||||||
|
|
||||||
|
for (let i = 0; i < this.categories.length; i++) {
|
||||||
|
if (this.selectedCategories[i]) {
|
||||||
|
this.deleteCategory(this.categories[i].id)
|
||||||
|
.then(() => {
|
||||||
|
// this.loadCategories();
|
||||||
|
// this.$toast.open({
|
||||||
|
// duration: 3000,
|
||||||
|
// message: this.$i18n.get('info_category_deleted'),
|
||||||
|
// position: 'is-bottom',
|
||||||
|
// type: 'is-secondary',
|
||||||
|
// queue: false
|
||||||
|
// })
|
||||||
|
}).catch(() => {
|
||||||
|
// this.$toast.open({
|
||||||
|
// duration: 3000,
|
||||||
|
// message: this.$i18n.get('info_error_deleting_category'),
|
||||||
|
// position: 'is-bottom',
|
||||||
|
// type: 'is-danger',
|
||||||
|
// queue: false
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.allCategoriesOnPageSelected = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -181,7 +181,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex'
|
import { mapActions } from 'vuex';
|
||||||
|
import CustomDialog from '../other/custom-dialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CollectionsList',
|
name: 'CollectionsList',
|
||||||
|
@ -229,63 +230,76 @@ export default {
|
||||||
this.selectedCollections.splice(i, 1, !this.allCollectionsOnPageSelected);
|
this.selectedCollections.splice(i, 1, !this.allCollectionsOnPageSelected);
|
||||||
},
|
},
|
||||||
deleteOneCollection(collectionId) {
|
deleteOneCollection(collectionId) {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.isOnTrash ? this.$i18n.get('info_warning_collection_delete') : this.$i18n.get('info_warning_collection_trash'),
|
parent: this,
|
||||||
onConfirm: () => {
|
component: CustomDialog,
|
||||||
this.deleteCollection({ collectionId: collectionId, isPermanently: this.isOnTrash })
|
props: {
|
||||||
.then(() => {
|
icon: 'alert',
|
||||||
// this.$toast.open({
|
title: this.$i18n.get('label_warning'),
|
||||||
// duration: 3000,
|
message: this.isOnTrash ? this.$i18n.get('info_warning_collection_delete') : this.$i18n.get('info_warning_collection_trash'),
|
||||||
// message: this.$i18n.get('info_collection_deleted'),
|
onConfirm: () => {
|
||||||
// position: 'is-bottom',
|
this.deleteCollection({ collectionId: collectionId, isPermanently: this.isOnTrash })
|
||||||
// type: 'is-secondary',
|
.then(() => {
|
||||||
// queue: true
|
// this.$toast.open({
|
||||||
// });
|
// duration: 3000,
|
||||||
for (let i = 0; i < this.selectedCollections.length; i++) {
|
// message: this.$i18n.get('info_collection_deleted'),
|
||||||
if (this.selectedCollections[i].id == collectionId)
|
// position: 'is-bottom',
|
||||||
this.selectedCollections.splice(i, 1);
|
// type: 'is-secondary',
|
||||||
}
|
// queue: true
|
||||||
}).catch(() => {
|
// });
|
||||||
// this.$toast.open({
|
for (let i = 0; i < this.selectedCollections.length; i++) {
|
||||||
// duration: 3000,
|
if (this.selectedCollections[i].id == collectionId)
|
||||||
// message: this.$i18n.get('info_error_deleting_collection'),
|
this.selectedCollections.splice(i, 1);
|
||||||
// position: 'is-bottom',
|
}
|
||||||
// type: 'is-danger',
|
}).catch(() => {
|
||||||
// queue: true
|
// this.$toast.open({
|
||||||
// })
|
// duration: 3000,
|
||||||
});
|
// message: this.$i18n.get('info_error_deleting_collection'),
|
||||||
|
// position: 'is-bottom',
|
||||||
|
// type: 'is-danger',
|
||||||
|
// queue: true
|
||||||
|
// })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
deleteSelectedCollections() {
|
deleteSelectedCollections() {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.isOnTrash ? this.$i18n.get('info_warning_selected_collections_delete') : this.$i18n.get('info_warning_selected_collections_trash'),
|
parent: this,
|
||||||
onConfirm: () => {
|
component: CustomDialog,
|
||||||
|
props: {
|
||||||
|
icon: 'alert',
|
||||||
|
title: this.$i18n.get('label_warning'),
|
||||||
|
message: this.isOnTrash ? this.$i18n.get('info_warning_selected_collections_delete') : this.$i18n.get('info_warning_selected_collections_trash'),
|
||||||
|
onConfirm: () => {
|
||||||
|
|
||||||
for (let i = 0; i < this.collections.length; i++) {
|
for (let i = 0; i < this.collections.length; i++) {
|
||||||
if (this.selectedCollections[i]) {
|
if (this.selectedCollections[i]) {
|
||||||
this.deleteCollection({ collectionId: this.collections[i].id, isPermanently: this.isOnTrash })
|
this.deleteCollection({ collectionId: this.collections[i].id, isPermanently: this.isOnTrash })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// this.loadCollections();
|
// this.loadCollections();
|
||||||
// this.$toast.open({
|
// this.$toast.open({
|
||||||
// duration: 3000,
|
// duration: 3000,
|
||||||
// message: this.$i18n.get('info_collection_deleted'),
|
// message: this.$i18n.get('info_collection_deleted'),
|
||||||
// position: 'is-bottom',
|
// position: 'is-bottom',
|
||||||
// type: 'is-secondary',
|
// type: 'is-secondary',
|
||||||
// queue: false
|
// queue: false
|
||||||
// })
|
// })
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// this.$toast.open({
|
// this.$toast.open({
|
||||||
// duration: 3000,
|
// duration: 3000,
|
||||||
// message: this.$i18n.get('info_error_deleting_collection'),
|
// message: this.$i18n.get('info_error_deleting_collection'),
|
||||||
// position: 'is-bottom',
|
// position: 'is-bottom',
|
||||||
// type: 'is-danger',
|
// type: 'is-danger',
|
||||||
// queue: false
|
// queue: false
|
||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
this.allCollectionsOnPageSelected = false;
|
||||||
this.allCollectionsOnPageSelected = false;
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -359,6 +373,10 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img.table-thumb {
|
||||||
|
border-radius: 50px !important;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,10 @@
|
||||||
:options="{
|
:options="{
|
||||||
group: { name:'fields', pull: false, put: true },
|
group: { name:'fields', pull: false, put: true },
|
||||||
sort: openedFieldId == '' || openedFieldId == undefined,
|
sort: openedFieldId == '' || openedFieldId == undefined,
|
||||||
disabled: openedFieldId != '' && openedFieldId != undefined,
|
//disabled: openedFieldId != '' && openedFieldId != undefined,
|
||||||
handle: '.handle',
|
handle: '.handle',
|
||||||
ghostClass: 'sortable-ghost',
|
ghostClass: 'sortable-ghost',
|
||||||
|
chosenClass: 'sortable-chosen',
|
||||||
filter: 'not-sortable-item',
|
filter: 'not-sortable-item',
|
||||||
animation: '250'}">
|
animation: '250'}">
|
||||||
<div
|
<div
|
||||||
|
@ -148,6 +149,7 @@
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
import GripIcon from '../other/grip-icon.vue';
|
import GripIcon from '../other/grip-icon.vue';
|
||||||
import FieldEditionForm from './../edition/field-edition-form.vue';
|
import FieldEditionForm from './../edition/field-edition-form.vue';
|
||||||
|
import CustomDialog from '../other/custom-dialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FieldsList',
|
name: 'FieldsList',
|
||||||
|
@ -194,16 +196,19 @@ export default {
|
||||||
hasUnsavedForms = true;
|
hasUnsavedForms = true;
|
||||||
}
|
}
|
||||||
if ((this.openedFieldId != '' && this.openedFieldId != undefined) || hasUnsavedForms ) {
|
if ((this.openedFieldId != '' && this.openedFieldId != undefined) || hasUnsavedForms ) {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.$i18n.get('info_warning_fields_not_saved'),
|
parent: this,
|
||||||
|
component: CustomDialog,
|
||||||
|
props: {
|
||||||
|
icon: 'alert',
|
||||||
|
title: this.$i18n.get('label_warning'),
|
||||||
|
message: this.$i18n.get('info_warning_fields_not_saved'),
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
this.onEditionCanceled();
|
this.onEditionCanceled();
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
cancelText: this.$i18n.get('cancel'),
|
}
|
||||||
confirmText: this.$i18n.get('continue'),
|
});
|
||||||
type: 'is-secondary'
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
:options="{
|
:options="{
|
||||||
group: { name:'filters', pull: false, put: true },
|
group: { name:'filters', pull: false, put: true },
|
||||||
sort: openedFilterId == '' || openedFilterId == undefined,
|
sort: openedFilterId == '' || openedFilterId == undefined,
|
||||||
disabled: openedFilterId != '' && openedFilterId != undefined,
|
//disabled: openedFilterId != '' && openedFilterId != undefined,
|
||||||
handle: '.handle',
|
handle: '.handle',
|
||||||
ghostClass: 'sortable-ghost',
|
ghostClass: 'sortable-ghost',
|
||||||
filter: 'not-sortable-item',
|
filter: 'not-sortable-item',
|
||||||
|
@ -141,6 +141,7 @@
|
||||||
}">
|
}">
|
||||||
<div
|
<div
|
||||||
class="available-field-item"
|
class="available-field-item"
|
||||||
|
v-if="field.enabled"
|
||||||
v-for="(field, index) in availableFieldList"
|
v-for="(field, index) in availableFieldList"
|
||||||
:key="index"
|
:key="index"
|
||||||
@click.prevent="addFieldViaButton(field, index)">
|
@click.prevent="addFieldViaButton(field, index)">
|
||||||
|
@ -177,6 +178,7 @@
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
import GripIcon from '../other/grip-icon.vue';
|
import GripIcon from '../other/grip-icon.vue';
|
||||||
import FilterEditionForm from './../edition/filter-edition-form.vue';
|
import FilterEditionForm from './../edition/filter-edition-form.vue';
|
||||||
|
import CustomDialog from '../other/custom-dialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FiltersList',
|
name: 'FiltersList',
|
||||||
|
@ -221,16 +223,19 @@ export default {
|
||||||
hasUnsavedForms = true;
|
hasUnsavedForms = true;
|
||||||
}
|
}
|
||||||
if ((this.openedFilterId != '' && this.openedFilterId != undefined) || hasUnsavedForms ) {
|
if ((this.openedFilterId != '' && this.openedFilterId != undefined) || hasUnsavedForms ) {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.$i18n.get('info_warning_filters_not_saved'),
|
parent: this,
|
||||||
|
component: CustomDialog,
|
||||||
|
props: {
|
||||||
|
icon: 'alert',
|
||||||
|
title: this.$i18n.get('label_warning'),
|
||||||
|
message: this.$i18n.get('info_warning_filters_not_saved'),
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
this.onEditionCanceled();
|
this.onEditionCanceled();
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
cancelText: this.$i18n.get('cancel'),
|
}
|
||||||
confirmText: this.$i18n.get('continue'),
|
});
|
||||||
type: 'is-secondary'
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,149 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="tainacan-table">
|
|
||||||
|
<!-- GRID VIEW MODE -->
|
||||||
|
<div
|
||||||
|
class="tainacan-grid-container"
|
||||||
|
v-if="viewMode == 'grid'">
|
||||||
|
<div
|
||||||
|
:key="index"
|
||||||
|
v-for="(item, index) of items"
|
||||||
|
:class="{ 'selected-grid-item': selectedItems[index] }"
|
||||||
|
class="tainacan-grid-item">
|
||||||
|
|
||||||
|
<!-- Checkbox -->
|
||||||
|
<div
|
||||||
|
:class="{ 'is-selecting': isSelectingItems }"
|
||||||
|
class="grid-item-checkbox">
|
||||||
|
<b-checkbox
|
||||||
|
size="is-small"
|
||||||
|
v-model="selectedItems[index]"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<p
|
||||||
|
v-for="(column, index) in tableFields"
|
||||||
|
:key="index"
|
||||||
|
v-if="column.display && column.field_type_object != undefined && (column.field_type_object.related_mapped_prop == 'title')"
|
||||||
|
class="metadata-title"
|
||||||
|
@click="goToItemPage(item)"
|
||||||
|
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''"/>
|
||||||
|
|
||||||
|
<!-- Thumbnail -->
|
||||||
|
<a
|
||||||
|
v-if="item.thumbnail != undefined"
|
||||||
|
@click="goToItemPage(item)">
|
||||||
|
<img :src="item['thumbnail'].medium ? item['thumbnail'].medium : thumbPlaceholderPath">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Actions -->
|
||||||
|
<div
|
||||||
|
v-if="item.current_user_can_edit"
|
||||||
|
class="actions-area"
|
||||||
|
:label="$i18n.get('label_actions')">
|
||||||
|
<a
|
||||||
|
id="button-edit"
|
||||||
|
:aria-label="$i18n.getFrom('items','edit_item')"
|
||||||
|
@click.prevent.stop="goToItemEditPage(item.id)">
|
||||||
|
<b-icon
|
||||||
|
type="is-secondary"
|
||||||
|
icon="pencil"/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
id="button-delete"
|
||||||
|
:aria-label="$i18n.get('label_button_delete')"
|
||||||
|
@click.prevent.stop="deleteOneItem(item.id)">
|
||||||
|
<b-icon
|
||||||
|
type="is-secondary"
|
||||||
|
:icon="!isOnTrash ? 'delete' : 'delete-forever'"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- CARDS VIEW MODE -->
|
||||||
|
<div
|
||||||
|
class="tainacan-cards-container"
|
||||||
|
v-if="viewMode == 'cards'">
|
||||||
|
<div
|
||||||
|
:key="index"
|
||||||
|
v-for="(item, index) of items"
|
||||||
|
:class="{ 'selected-card': selectedItems[index] }"
|
||||||
|
class="tainacan-card">
|
||||||
|
|
||||||
|
<!-- Checkbox -->
|
||||||
|
<div
|
||||||
|
:class="{ 'is-selecting': isSelectingItems }"
|
||||||
|
class="card-checkbox">
|
||||||
|
<b-checkbox
|
||||||
|
size="is-small"
|
||||||
|
v-model="selectedItems[index]"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<p
|
||||||
|
v-for="(column, index) in tableFields"
|
||||||
|
:key="index"
|
||||||
|
v-if="column.display && column.field_type_object != undefined && (column.field_type_object.related_mapped_prop == 'title')"
|
||||||
|
class="metadata-title"
|
||||||
|
@click="goToItemPage(item)"
|
||||||
|
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''" />
|
||||||
|
|
||||||
|
<!-- Actions -->
|
||||||
|
<div
|
||||||
|
v-if="item.current_user_can_edit"
|
||||||
|
class="actions-area"
|
||||||
|
:label="$i18n.get('label_actions')">
|
||||||
|
<a
|
||||||
|
id="button-edit"
|
||||||
|
:aria-label="$i18n.getFrom('items','edit_item')"
|
||||||
|
@click.prevent.stop="goToItemEditPage(item.id)">
|
||||||
|
<b-icon
|
||||||
|
type="is-secondary"
|
||||||
|
icon="pencil"/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
id="button-delete"
|
||||||
|
:aria-label="$i18n.get('label_button_delete')"
|
||||||
|
@click.prevent.stop="deleteOneItem(item.id)">
|
||||||
|
<b-icon
|
||||||
|
type="is-secondary"
|
||||||
|
:icon="!isOnTrash ? 'delete' : 'delete-forever'"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Remaining metadata -->
|
||||||
|
<div
|
||||||
|
class="media"
|
||||||
|
@click="goToItemPage(item)">
|
||||||
|
<a
|
||||||
|
v-if="item.thumbnail != undefined"
|
||||||
|
@click="goToItemPage(item)">
|
||||||
|
<img :src="item['thumbnail'].medium_large ? item['thumbnail'].medium_large : thumbPlaceholderPath">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="list-metadata media-body">
|
||||||
|
<span
|
||||||
|
v-for="(column, index) in tableFields"
|
||||||
|
:key="index"
|
||||||
|
v-if="column.display && column.slug != 'thumbnail' && column.field_type_object != undefined && (column.field_type_object.related_mapped_prop != 'title')">
|
||||||
|
<h3 class="metadata-label">{{ column.name }}</h3>
|
||||||
|
<p
|
||||||
|
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''"
|
||||||
|
class="metadata-value"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- TABLE VIEW MODE -->
|
||||||
|
<table
|
||||||
|
v-if="viewMode == 'table'"
|
||||||
|
class="tainacan-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<!-- Checking list -->
|
<!-- Checking list -->
|
||||||
|
@ -84,8 +226,6 @@
|
||||||
v-for="(column, index) in tableFields"
|
v-for="(column, index) in tableFields"
|
||||||
v-if="column.display"
|
v-if="column.display"
|
||||||
:label="column.name"
|
:label="column.name"
|
||||||
:aria-label="(column.field != 'row_thumbnail' && column.field != 'row_creation' && column.field != 'row_author')
|
|
||||||
? column.name + '' + (item.metadata ? item.metadata[column.slug].value_as_string : '') : ''"
|
|
||||||
class="column-default-width"
|
class="column-default-width"
|
||||||
:class="{
|
:class="{
|
||||||
'thumbnail-cell': column.field == 'row_thumbnail',
|
'thumbnail-cell': column.field == 'row_thumbnail',
|
||||||
|
@ -119,7 +259,7 @@
|
||||||
<span v-if="column.field == 'row_thumbnail'">
|
<span v-if="column.field == 'row_thumbnail'">
|
||||||
<img
|
<img
|
||||||
class="table-thumb"
|
class="table-thumb"
|
||||||
:src="item[column.slug].thumb">
|
:src="item['thumbnail'].thumb ? item['thumbnail'].thumb : thumbPlaceholderPath">
|
||||||
</span>
|
</span>
|
||||||
<p
|
<p
|
||||||
v-tooltip="{
|
v-tooltip="{
|
||||||
|
@ -167,6 +307,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex';
|
import { mapActions } from 'vuex';
|
||||||
|
import CustomDialog from '../other/custom-dialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ItemsList',
|
name: 'ItemsList',
|
||||||
|
@ -175,6 +316,7 @@ export default {
|
||||||
allItemsOnPageSelected: false,
|
allItemsOnPageSelected: false,
|
||||||
isSelectingItems: false,
|
isSelectingItems: false,
|
||||||
selectedItems: [],
|
selectedItems: [],
|
||||||
|
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -182,12 +324,13 @@ export default {
|
||||||
tableFields: Array,
|
tableFields: Array,
|
||||||
items: Array,
|
items: Array,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isOnTrash: false
|
isOnTrash: false,
|
||||||
|
viewMode: 'table'
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.selectedItems = [];
|
this.selectedItems = [];
|
||||||
for (let i = 0; i < this.items.length; i++)
|
for (let i = 0; i < this.items.length; i++)
|
||||||
this.selectedItems.push(false);
|
this.selectedItems.push(false);
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
selectedItems() {
|
selectedItems() {
|
||||||
|
@ -213,68 +356,80 @@ export default {
|
||||||
this.selectedItems.splice(i, 1, !this.allItemsOnPageSelected);
|
this.selectedItems.splice(i, 1, !this.allItemsOnPageSelected);
|
||||||
},
|
},
|
||||||
deleteOneItem(itemId) {
|
deleteOneItem(itemId) {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.isOnTrash ? this.$i18n.get('info_warning_item_delete') : this.$i18n.get('info_warning_item_trash'),
|
parent: this,
|
||||||
onConfirm: () => {
|
component: CustomDialog,
|
||||||
this.deleteItem({ itemId: itemId, isPermanently: this.isOnTrash })
|
props: {
|
||||||
.then(() => {
|
icon: 'alert',
|
||||||
// this.$toast.open({
|
title: this.$i18n.get('label_warning'),
|
||||||
// duration: 3000,
|
message: this.isOnTrash ? this.$i18n.get('info_warning_item_delete') : this.$i18n.get('info_warning_item_trash'),
|
||||||
// message: this.$i18n.get('info_item_deleted'),
|
onConfirm: () => {
|
||||||
// position: 'is-bottom',
|
this.deleteItem({ itemId: itemId, isPermanently: this.isOnTrash })
|
||||||
// type: 'is-secondary',
|
// .then(() => {
|
||||||
// queue: true
|
// // this.$toast.open({
|
||||||
// });
|
// // duration: 3000,
|
||||||
for (let i = 0; i < this.selectedItems.length; i++) {
|
// // message: this.$i18n.get('info_item_deleted'),
|
||||||
if (this.selectedItems[i].id == itemId)
|
// // position: 'is-bottom',
|
||||||
this.selectedItems.splice(i, 1);
|
// // type: 'is-secondary',
|
||||||
}
|
// // queue: true
|
||||||
}).catch(() => {
|
// // });
|
||||||
|
// for (let i = 0; i < this.selectedItems.length; i++) {
|
||||||
|
// if (this.selectedItems[i].id == itemId)
|
||||||
|
// this.selectedItems.splice(i, 1);
|
||||||
|
// }
|
||||||
|
// }).catch(() => {
|
||||||
|
|
||||||
// this.$toast.open({
|
// // this.$toast.open({
|
||||||
// duration: 3000,
|
// // duration: 3000,
|
||||||
// message: this.$i18n.get('info_error_deleting_item'),
|
// // message: this.$i18n.get('info_error_deleting_item'),
|
||||||
// position: 'is-bottom',
|
// // position: 'is-bottom',
|
||||||
// type: 'is-danger',
|
// // type: 'is-danger',
|
||||||
// queue: true
|
// // queue: true
|
||||||
// })
|
// // })
|
||||||
});
|
// });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
deleteSelectedItems() {
|
deleteSelectedItems() {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.isOnTrash ? this.$i18n.get('info_warning_selected_items_delete') : this.$i18n.get('info_warning_selected_items_trash'),
|
parent: this,
|
||||||
onConfirm: () => {
|
component: CustomDialog,
|
||||||
|
props: {
|
||||||
|
icon: 'alert',
|
||||||
|
title: this.$i18n.get('label_warning'),
|
||||||
|
message: this.isOnTrash ? this.$i18n.get('info_warning_selected_items_delete') : this.$i18n.get('info_warning_selected_items_trash'),
|
||||||
|
onConfirm: () => {
|
||||||
|
|
||||||
for (let i = 0; i < this.selectedItems.length; i++) {
|
for (let i = 0; i < this.selectedItems.length; i++) {
|
||||||
if (this.selectedItems[i]) {
|
if (this.selectedItems[i]) {
|
||||||
this.deleteItem({ itemId: this.items[i].id, isPermanently: this.isOnTrash })
|
this.deleteItem({ itemId: this.items[i].id, isPermanently: this.isOnTrash })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// this.$toast.open({
|
// this.$toast.open({
|
||||||
// duration: 3000,
|
// duration: 3000,
|
||||||
// message: this.$i18n.get('info_item_deleted'),
|
// message: this.$i18n.get('info_item_deleted'),
|
||||||
// position: 'is-bottom',
|
// position: 'is-bottom',
|
||||||
// type: 'is-secondary',
|
// type: 'is-secondary',
|
||||||
// queue: false
|
// queue: false
|
||||||
// });
|
// });
|
||||||
for (let i = 0; i < this.selectedItems.length; i++) {
|
for (let i = 0; i < this.selectedItems.length; i++) {
|
||||||
if (this.selectedItems[i].id == this.itemId)
|
if (this.selectedItems[i].id == this.itemId)
|
||||||
this.selectedItems.splice(i, 1);
|
this.selectedItems.splice(i, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// this.$toast.open({
|
// this.$toast.open({
|
||||||
// duration: 3000,
|
// duration: 3000,
|
||||||
// message: this.$i18n.get('info_error_deleting_item'),
|
// message: this.$i18n.get('info_error_deleting_item'),
|
||||||
// position: 'is-bottom',
|
// position: 'is-bottom',
|
||||||
// type: 'is-danger',
|
// type: 'is-danger',
|
||||||
// queue: false
|
// queue: false
|
||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.allItemsOnPageSelected = false;
|
||||||
}
|
}
|
||||||
this.allItemsOnPageSelected = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -303,6 +458,8 @@ export default {
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
@import "../../scss/_variables.scss";
|
@import "../../scss/_variables.scss";
|
||||||
|
@import "../../scss/_view-mode-grid.scss";
|
||||||
|
@import "../../scss/_view-mode-cards.scss";
|
||||||
|
|
||||||
.selection-control {
|
.selection-control {
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
import TermEditionForm from '../edition/term-edition-form.vue'
|
import TermEditionForm from '../edition/term-edition-form.vue';
|
||||||
|
import CustomDialog from '../other/custom-dialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TermsList',
|
name: 'TermsList',
|
||||||
|
@ -212,14 +213,16 @@ export default {
|
||||||
|
|
||||||
// Checks if user is deleting a term with unsaved info.
|
// Checks if user is deleting a term with unsaved info.
|
||||||
if (term.id == 'new' || !term.saved || term.opened) {
|
if (term.id == 'new' || !term.saved || term.opened) {
|
||||||
this.$dialog.confirm({
|
this.$modal.open({
|
||||||
message: this.$i18n.get('info_warning_terms_not_saved'),
|
parent: this,
|
||||||
onCancel: () => { return },
|
component: CustomDialog,
|
||||||
onConfirm: () => { this.removeTerm(term);},
|
props: {
|
||||||
cancelText: this.$i18n.get('cancel'),
|
icon: 'alert',
|
||||||
confirmText: this.$i18n.get('continue'),
|
title: this.$i18n.get('label_warning'),
|
||||||
type: 'is-secondary'
|
message: this.$i18n.get('info_warning_terms_not_saved'),
|
||||||
});
|
onConfirm: () => { this.removeTerm(term); },
|
||||||
|
}
|
||||||
|
});
|
||||||
} else{
|
} else{
|
||||||
this.removeTerm(term);
|
this.removeTerm(term);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,7 @@
|
||||||
tag="a"
|
tag="a"
|
||||||
to="/events"
|
to="/events"
|
||||||
:class="activeRoute == 'EventsPage' ? 'is-active':''">
|
:class="activeRoute == 'EventsPage' ? 'is-active':''">
|
||||||
<b-icon
|
<activities-icon />
|
||||||
size="is-small"
|
|
||||||
icon="flash"/>
|
|
||||||
<span class="menu-text">{{ $i18n.get('events') }}</span>
|
<span class="menu-text">{{ $i18n.get('events') }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
@ -81,13 +79,17 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
import ActivitiesIcon from '../other/activities-icon.vue';
|
||||||
name: 'PrimaryMenu',
|
export default {
|
||||||
props: {
|
name: 'PrimaryMenu',
|
||||||
isMenuCompressed: false,
|
props: {
|
||||||
activeRoute: '/collections'
|
isMenuCompressed: false,
|
||||||
}
|
activeRoute: '/collections'
|
||||||
}
|
},
|
||||||
|
components: {
|
||||||
|
ActivitiesIcon
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -121,10 +123,19 @@
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
-webkit-transition: padding 0.2s linear; /* Safari */
|
-webkit-transition: padding 0.2s linear; /* Safari */
|
||||||
transition: padding 0.2s linear;
|
transition: padding 0.2s linear;
|
||||||
|
|
||||||
|
.activities-icon {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover, a.is-active {
|
a:hover, a.is-active {
|
||||||
background-color: $primary;
|
background-color: $primary;
|
||||||
color: $tertiary;
|
color: $tertiary;
|
||||||
|
|
||||||
|
.activities-icon {
|
||||||
|
fill: $tertiary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
a:focus {
|
a:focus {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<div class="control has-icons-right is-small is-clearfix">
|
<div class="control has-icons-right is-small is-clearfix">
|
||||||
<input
|
<input
|
||||||
autocomplete="on"
|
autocomplete="on"
|
||||||
:placeholder="$i18n.get('instruction_search_repository')"
|
:placeholder="$i18n.get('instruction_search_on_repository')"
|
||||||
class="input is-small"
|
class="input is-small"
|
||||||
type="search"
|
type="search"
|
||||||
v-model="searchTerm">
|
v-model="searchTerm">
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<i class="mdi mdi-magnify" />
|
<i class="mdi mdi-magnify" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="">{{ $i18n.get('advanced_search') }}</a>
|
<a @click="toItemsPage">{{ $i18n.get('advanced_search') }}</a>
|
||||||
</span>
|
</span>
|
||||||
<a
|
<a
|
||||||
class="level-item"
|
class="level-item"
|
||||||
|
@ -50,6 +50,16 @@ export default {
|
||||||
searchTerm: ''
|
searchTerm: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
toItemsPage(){
|
||||||
|
this.$router.push({
|
||||||
|
path: '/items',
|
||||||
|
query: {
|
||||||
|
openAdvancedSearch: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
isMenuCompressed: false
|
isMenuCompressed: false
|
||||||
}
|
}
|
||||||
|
@ -105,12 +115,13 @@ export default {
|
||||||
color: $tertiary;
|
color: $tertiary;
|
||||||
}
|
}
|
||||||
.search-area {
|
.search-area {
|
||||||
display: none;//display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-right: 36px;
|
margin-right: 36px;
|
||||||
|
|
||||||
.control {
|
.control {
|
||||||
input {
|
input {
|
||||||
|
border-width: 0 !important;
|
||||||
height: 27px;
|
height: 27px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: $gray-light;
|
color: $gray-light;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
{{ arrayViewPath[index] }}
|
{{ arrayViewPath[index] }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<span v-if="index == arrayRealPath.length - 1">{{ arrayViewPath[index] }}</span>
|
<span v-if="index == arrayRealPath.length - 1">{{ arrayViewPath[index] }}</span>
|
||||||
<span v-if="index != arrayRealPath.length - 1"> > </span>
|
<span v-if="index != arrayRealPath.length - 1 && arrayViewPath[index]"> > </span>
|
||||||
</span>
|
</span>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
@ -83,9 +83,7 @@
|
||||||
:to="{ path: $routerHelper.getCollectionEventsPath(id) }"
|
:to="{ path: $routerHelper.getCollectionEventsPath(id) }"
|
||||||
:class="activeRoute == 'CollectionEventsPage' ? 'is-active':''"
|
:class="activeRoute == 'CollectionEventsPage' ? 'is-active':''"
|
||||||
:aria-label="$i18n.get('label_collection_events')">
|
:aria-label="$i18n.get('label_collection_events')">
|
||||||
<b-icon
|
<activities-icon />
|
||||||
size="is-small"
|
|
||||||
icon="flash"/>
|
|
||||||
<br>
|
<br>
|
||||||
<span class="menu-text">{{ $i18n.get('events') }}</span>
|
<span class="menu-text">{{ $i18n.get('events') }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -97,6 +95,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
|
import ActivitiesIcon from '../other/activities-icon.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TainacanSubheader',
|
name: 'TainacanSubheader',
|
||||||
|
@ -109,6 +108,9 @@ export default {
|
||||||
activeRouteName: '',
|
activeRouteName: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
ActivitiesIcon
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
id: Number,
|
id: Number,
|
||||||
},
|
},
|
||||||
|
@ -130,7 +132,8 @@ export default {
|
||||||
'fetchCollectionName'
|
'fetchCollectionName'
|
||||||
]),
|
]),
|
||||||
...mapGetters('collection', [
|
...mapGetters('collection', [
|
||||||
'getCollectionName'
|
'getCollectionName',
|
||||||
|
'getCollection'
|
||||||
]),
|
]),
|
||||||
...mapActions('item', [
|
...mapActions('item', [
|
||||||
'fetchItemTitle'
|
'fetchItemTitle'
|
||||||
|
@ -160,6 +163,7 @@ export default {
|
||||||
this.fetchCollectionName(this.arrayRealPath[i])
|
this.fetchCollectionName(this.arrayRealPath[i])
|
||||||
.then(collectionName => this.arrayViewPath.splice(i, 1, collectionName))
|
.then(collectionName => this.arrayViewPath.splice(i, 1, collectionName))
|
||||||
.catch((error) => this.$console.error(error));
|
.catch((error) => this.$console.error(error));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'items':
|
case 'items':
|
||||||
this.fetchItemTitle(this.arrayRealPath[i])
|
this.fetchItemTitle(this.arrayRealPath[i])
|
||||||
|
@ -179,7 +183,11 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.arrayViewPath.splice(i, 1, this.$i18n.get(this.arrayRealPath[i]));
|
if(this.arrayRealPath[i] == 'undefined'){
|
||||||
|
this.arrayViewPath.splice(i, 1, '');
|
||||||
|
} else {
|
||||||
|
this.arrayViewPath.splice(i, 1, this.$i18n.get(this.arrayRealPath[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -192,7 +200,7 @@ export default {
|
||||||
|
|
||||||
this.arrayRealPath = this.$route.path.split("/");
|
this.arrayRealPath = this.$route.path.split("/");
|
||||||
this.arrayRealPath = this.arrayRealPath.filter((item) => item.length != 0);
|
this.arrayRealPath = this.arrayRealPath.filter((item) => item.length != 0);
|
||||||
|
|
||||||
this.generateViewPath();
|
this.generateViewPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
class="activities-icon"
|
||||||
|
xml:space="preserve">
|
||||||
|
<path
|
||||||
|
d="M20,11c0,1-0.2,2.1-0.5,3h-2.2c0.4-0.9,0.7-1.9,0.7-3c0-3.9-3.1-7-7-7s-7,3.1-7,7c0,3.5,2.6,6.5,6,6.9v2
|
||||||
|
c-4.5-0.5-8-4.3-8-8.9c0-5,4-9,9-9S20,6,20,11z M14,22h-2v-2h2V22z M14,18h-2v-2h2V18z M22,22h-6v-2h6V22z M22,18h-6v-2h6V18z M12,6
|
||||||
|
h-2l0,6l2.7,2H16l-4-3V6z"/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ActivitiesIcon'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style type="text/scss">
|
||||||
|
|
||||||
|
svg.activities-icon {
|
||||||
|
margin-bottom: -5px;
|
||||||
|
fill:#1E2F56;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="6.44px"
|
||||||
|
height="32.202px"
|
||||||
|
viewBox="0 0 6.44 32.202"
|
||||||
|
enable-background="new 0 0 6.44 32.202"
|
||||||
|
xml:space="preserve">
|
||||||
|
<path
|
||||||
|
fill="#BB3636"
|
||||||
|
d="M0,25.761h6.44v6.44H0V25.761 M0,0h6.44v19.321H0V0"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AlertIcon'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="38.819px"
|
||||||
|
height="29.746px"
|
||||||
|
viewBox="0 0 38.819 29.746"
|
||||||
|
enable-background="new 0 0 38.819 29.746"
|
||||||
|
xml:space="preserve">
|
||||||
|
<path
|
||||||
|
fill="#259F87"
|
||||||
|
d="M38.819,3.128L12.2,29.746L0,17.546l3.128-3.128l9.073,9.05L35.691,0L38.819,3.128z"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'CheckIcon'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
<template>
|
||||||
|
<div class="tainacan-form dialog">
|
||||||
|
<div
|
||||||
|
class="modal-card"
|
||||||
|
style="width: auto">
|
||||||
|
<div
|
||||||
|
v-if="icon != undefined && icon != ''"
|
||||||
|
class="modal-custom-icon">
|
||||||
|
<component :is="icon + '-icon'"/>
|
||||||
|
</div>
|
||||||
|
<section
|
||||||
|
class="modal-card-body">
|
||||||
|
<header
|
||||||
|
class="modal-card-head">
|
||||||
|
<h1 class="modal-card-title">{{ title }}</h1>
|
||||||
|
</header>
|
||||||
|
{{ message }}
|
||||||
|
</section>
|
||||||
|
<footer class="modal-card-foot form-submit">
|
||||||
|
<button
|
||||||
|
class="button is-outline"
|
||||||
|
type="button"
|
||||||
|
@click="$parent.close()">
|
||||||
|
{{ $i18n.get('cancel') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button is-success"
|
||||||
|
@click="onConfirm(); $parent.close();">
|
||||||
|
{{ $i18n.get('continue') }}
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import AlertIcon from './alert-icon.vue';
|
||||||
|
import CheckIcon from './check-icon.vue';
|
||||||
|
import QuestionIcon from './question-icon.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CustomDialog',
|
||||||
|
props: {
|
||||||
|
title: String,
|
||||||
|
message: String,
|
||||||
|
icon: String,
|
||||||
|
onConfirm: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
AlertIcon,
|
||||||
|
CheckIcon,
|
||||||
|
QuestionIcon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="19.749px"
|
||||||
|
height="33.073px"
|
||||||
|
viewBox="0 0 19.749 33.073"
|
||||||
|
enable-background="new 0 0 19.749 33.073"
|
||||||
|
xml:space="preserve">
|
||||||
|
<path
|
||||||
|
fill="#BB3636"
|
||||||
|
d="M6.615,28.112h4.961v4.961H6.615V28.112 M9.922,0c8.847,0.364,12.7,9.293,7.441,15.991
|
||||||
|
c-1.373,1.654-3.588,2.745-4.68,4.134c-1.108,1.373-1.108,3.026-1.108,4.68H6.615c0-2.762,0-5.093,1.108-6.747
|
||||||
|
c1.091-1.654,3.307-2.629,4.68-3.721c4.002-3.704,3.01-8.946-2.48-9.376c-2.74,0-4.961,2.221-4.961,4.961H0C0,4.442,4.442,0,9.922,0
|
||||||
|
z"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'QuestionIcon'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ const routes = [
|
||||||
|
|
||||||
{ path: '/collections', name: 'CollectionsPage', component: CollectionsPage, meta: {title: i18nGet('title_repository_collections_page'), icon: 'folder-multiple'} },
|
{ path: '/collections', name: 'CollectionsPage', component: CollectionsPage, meta: {title: i18nGet('title_repository_collections_page'), icon: 'folder-multiple'} },
|
||||||
{ path: '/collections/new', name: 'CollectionCreationForm', component: CollectionEditionForm, meta: {title: i18nGet('title_create_collection'), icon: 'folder-multiple'} },
|
{ path: '/collections/new', name: 'CollectionCreationForm', component: CollectionEditionForm, meta: {title: i18nGet('title_create_collection'), icon: 'folder-multiple'} },
|
||||||
|
{ path: '/collections/new/:mapper', name: 'MappedCollectionCreationForm', component: CollectionEditionForm, meta: {title: i18nGet('title_create_collection'), icon: 'folder-multiple'} },
|
||||||
|
|
||||||
{ path: '/collections/:collectionId', component: CollectionPage, meta: {title: i18nGet('title_collection_page'), icon: 'folder-multiple'},
|
{ path: '/collections/:collectionId', component: CollectionPage, meta: {title: i18nGet('title_collection_page'), icon: 'folder-multiple'},
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -212,6 +212,9 @@ RouterHelperPlugin.install = function (Vue, options = {}) {
|
||||||
getNewCollectionPath() {
|
getNewCollectionPath() {
|
||||||
return '/collections/new';
|
return '/collections/new';
|
||||||
},
|
},
|
||||||
|
getNewMappedCollectionPath(mapperSlug) {
|
||||||
|
return '/collections/new/' + mapperSlug;
|
||||||
|
},
|
||||||
getNewItemPath(collectionId) {
|
getNewItemPath(collectionId) {
|
||||||
return '/collections/' + collectionId + '/items/new';
|
return '/collections/' + collectionId + '/items/new';
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="primary-page page-container">
|
<div class="primary-page page-container">
|
||||||
|
<b-loading :active.sync="isLoadingFieldMappers"/>
|
||||||
<tainacan-title />
|
<tainacan-title />
|
||||||
<div
|
<div
|
||||||
class="sub-header"
|
class="sub-header"
|
||||||
|
@ -9,22 +10,29 @@
|
||||||
<button
|
<button
|
||||||
class="button is-secondary"
|
class="button is-secondary"
|
||||||
slot="trigger">
|
slot="trigger">
|
||||||
<span>{{ $i18n.getFrom('collections','new_item') }}</span>
|
<div>{{ $i18n.getFrom('collections', 'new_item') }}</div>
|
||||||
<b-icon icon="menu-down"/>
|
<b-icon icon="menu-down"/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<b-dropdown-item>
|
<b-dropdown-item>
|
||||||
<router-link
|
<router-link
|
||||||
id="a-create-collection"
|
id="a-create-collection"
|
||||||
tag="div"
|
tag="div"
|
||||||
:to="{ path: $routerHelper.getNewCollectionPath() }">
|
:to="{ path: $routerHelper.getNewCollectionPath() }">
|
||||||
{{ $i18n.get('label_blank_collection') }}
|
{{ $i18n.get('new_blank_collection') }}
|
||||||
<br>
|
<br>
|
||||||
<small class="is-small">{{ $i18n.get('info_choose_your_metadata') }}</small>
|
<small class="is-small">{{ $i18n.get('info_choose_your_metadata') }}</small>
|
||||||
</router-link>
|
</router-link>
|
||||||
</b-dropdown-item>
|
</b-dropdown-item>
|
||||||
<b-dropdown-item disabled>
|
<b-dropdown-item
|
||||||
{{ $i18n.get('label_dublin_core') + ' (Not ready)' }}
|
:key="field_mapper.slug"
|
||||||
|
v-for="field_mapper in field_mappers"
|
||||||
|
v-if="field_mapper.metadata != false">
|
||||||
|
<router-link
|
||||||
|
:id="'a-create-collection-' + field_mapper.slug"
|
||||||
|
tag="div"
|
||||||
|
:to="{ path: $routerHelper.getNewMappedCollectionPath(field_mapper.slug) }">
|
||||||
|
{{ $i18n.get(field_mapper.name) }}
|
||||||
|
</router-link>
|
||||||
</b-dropdown-item>
|
</b-dropdown-item>
|
||||||
</b-dropdown>
|
</b-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,6 +140,7 @@ export default {
|
||||||
totalCollections: 0,
|
totalCollections: 0,
|
||||||
page: 1,
|
page: 1,
|
||||||
collectionsPerPage: 12,
|
collectionsPerPage: 12,
|
||||||
|
isLoadingFieldMappers: true,
|
||||||
status: ''
|
status: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -142,9 +151,15 @@ export default {
|
||||||
...mapActions('collection', [
|
...mapActions('collection', [
|
||||||
'fetchCollections',
|
'fetchCollections',
|
||||||
]),
|
]),
|
||||||
|
...mapActions('fields', [
|
||||||
|
'fetchFieldMappers'
|
||||||
|
]),
|
||||||
...mapGetters('collection', [
|
...mapGetters('collection', [
|
||||||
'getCollections'
|
'getCollections'
|
||||||
]),
|
]),
|
||||||
|
...mapGetters('fields', [
|
||||||
|
'getFieldMappers'
|
||||||
|
]),
|
||||||
onChangeTab(status) {
|
onChangeTab(status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.loadCollections();
|
this.loadCollections();
|
||||||
|
@ -177,11 +192,17 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
field_mappers: {
|
||||||
|
get() {
|
||||||
|
return this.getFieldMappers();
|
||||||
|
}
|
||||||
|
},
|
||||||
collections() {
|
collections() {
|
||||||
return this.getCollections();
|
return this.getCollections();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
this.isLoadingFieldTypes = true;
|
||||||
this.$userPrefs.get('collections_per_page')
|
this.$userPrefs.get('collections_per_page')
|
||||||
.then((value) => {
|
.then((value) => {
|
||||||
this.collectionsPerPage = value;
|
this.collectionsPerPage = value;
|
||||||
|
@ -189,6 +210,13 @@ export default {
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.$userPrefs.set('collections_per_page', 12, null);
|
this.$userPrefs.set('collections_per_page', 12, null);
|
||||||
});
|
});
|
||||||
|
this.fetchFieldMappers()
|
||||||
|
.then(() => {
|
||||||
|
this.isLoadingFieldMappers = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.isLoadingFieldMappers = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
mounted(){
|
mounted(){
|
||||||
this.loadCollections();
|
this.loadCollections();
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
<!-- SEARCH AND FILTERS --------------------- -->
|
<!-- SEARCH AND FILTERS --------------------- -->
|
||||||
<!-- Filter menu compress button -->
|
<!-- Filter menu compress button -->
|
||||||
<button
|
<button
|
||||||
|
v-if="!openAdvancedSearch"
|
||||||
id="filter-menu-compress-button"
|
id="filter-menu-compress-button"
|
||||||
:class="{'filter-menu-compress-button-top-repo': isRepositoryLevel}"
|
:class="{'filter-menu-compress-button-top-repo': isRepositoryLevel}"
|
||||||
:style="{ top: isHeaderShrinked ? '125px' : '152px'}"
|
:style="{ top: isHeaderShrinked ? '125px' : '152px'}"
|
||||||
|
@ -12,39 +13,34 @@
|
||||||
<b-icon :icon="isFiltersMenuCompressed ? 'menu-right' : 'menu-left'" />
|
<b-icon :icon="isFiltersMenuCompressed ? 'menu-right' : 'menu-left'" />
|
||||||
</button>
|
</button>
|
||||||
<!-- Side bar with search and filters -->
|
<!-- Side bar with search and filters -->
|
||||||
<aside
|
<aside
|
||||||
v-show="!isFiltersMenuCompressed"
|
v-show="!isFiltersMenuCompressed && !openAdvancedSearch"
|
||||||
class="filters-menu"
|
class="filters-menu"
|
||||||
:class="{ 'tainacan-form': isOnTheme }">
|
:class="{ 'tainacan-form': isOnTheme }">
|
||||||
<b-loading
|
<b-loading
|
||||||
:is-full-page="false"
|
:is-full-page="false"
|
||||||
:active.sync="isLoadingFilters"/>
|
:active.sync="isLoadingFilters"/>
|
||||||
|
|
||||||
<b-field>
|
<div class="search-area">
|
||||||
<div class="control is-small is-clearfix">
|
<div class="control has-icons-right is-small is-clearfix">
|
||||||
<input
|
<input
|
||||||
class="input is-small"
|
class="input is-small"
|
||||||
:placeholder="$i18n.get('instruction_search')"
|
:placeholder="$i18n.get('instruction_search')"
|
||||||
type="search"
|
type="search"
|
||||||
autocomplete="on"
|
autocomplete="on"
|
||||||
:value="searchQuery"
|
:value="searchQuery"
|
||||||
@input="futureSearchQuery = $event.target.value"
|
@input="futureSearchQuery = $event.target.value"
|
||||||
@keyup.enter="updateSearch()">
|
@keyup.enter="updateSearch()">
|
||||||
|
<span
|
||||||
|
@click="updateSearch()"
|
||||||
|
class="icon is-right">
|
||||||
|
<i class="mdi mdi-magnify" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<p class="control">
|
<a
|
||||||
<button
|
@click="openAdvancedSearch = !openAdvancedSearch"
|
||||||
id="collection-search-button"
|
class="is-size-7 is-secondary is-pulled-right">{{ $i18n.get('advanced_search') }}</a>
|
||||||
type="submit"
|
|
||||||
class="button"
|
|
||||||
@click="updateSearch()">
|
|
||||||
<b-icon
|
|
||||||
icon="magnify"
|
|
||||||
size="is-small"/>
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</b-field>
|
|
||||||
<!-- <a class="is-size-7 is-secondary is-pulled-right">Busca avançada</a> -->
|
|
||||||
|
|
||||||
<h3 class="has-text-weight-semibold">{{ $i18n.get('filters') }}</h3>
|
<h3 class="has-text-weight-semibold">{{ $i18n.get('filters') }}</h3>
|
||||||
<a
|
<a
|
||||||
|
@ -103,7 +99,9 @@
|
||||||
:active.sync="isLoadingItems"/>
|
:active.sync="isLoadingItems"/>
|
||||||
|
|
||||||
<!-- SEARCH CONTROL ------------------------- -->
|
<!-- SEARCH CONTROL ------------------------- -->
|
||||||
<div class="search-control">
|
<div
|
||||||
|
v-if="!openAdvancedSearch"
|
||||||
|
class="search-control">
|
||||||
<b-loading
|
<b-loading
|
||||||
:is-full-page="false"
|
:is-full-page="false"
|
||||||
:active.sync="isLoadingFields"/>
|
:active.sync="isLoadingFields"/>
|
||||||
|
@ -145,12 +143,12 @@
|
||||||
<b-dropdown
|
<b-dropdown
|
||||||
ref="displayedFieldsDropdown"
|
ref="displayedFieldsDropdown"
|
||||||
:mobile-modal="false"
|
:mobile-modal="false"
|
||||||
:disabled="totalItems <= 0"
|
:disabled="totalItems <= 0 || adminViewMode == 'grid'"
|
||||||
class="show">
|
class="show">
|
||||||
<button
|
<button
|
||||||
class="button is-white"
|
class="button is-white"
|
||||||
slot="trigger">
|
slot="trigger">
|
||||||
<span>{{ $i18n.get('label_table_fields') }}</span>
|
<span>{{ $i18n.get('label_displayed_metadata') }}</span>
|
||||||
<b-icon icon="menu-down"/>
|
<b-icon icon="menu-down"/>
|
||||||
</button>
|
</button>
|
||||||
<div class="metadata-options-container">
|
<div class="metadata-options-container">
|
||||||
|
@ -213,7 +211,7 @@
|
||||||
v-if="isOnTheme"
|
v-if="isOnTheme"
|
||||||
class="search-control-item">
|
class="search-control-item">
|
||||||
<b-field>
|
<b-field>
|
||||||
<b-dropdown
|
<b-dropdown
|
||||||
@change="onChangeViewMode($event)"
|
@change="onChangeViewMode($event)"
|
||||||
:mobile-modal="false"
|
:mobile-modal="false"
|
||||||
position="is-bottom-left"
|
position="is-bottom-left"
|
||||||
|
@ -224,6 +222,7 @@
|
||||||
<span
|
<span
|
||||||
v-if="registeredViewModes[viewMode] != undefined"
|
v-if="registeredViewModes[viewMode] != undefined"
|
||||||
v-html="registeredViewModes[viewMode].icon"/>
|
v-html="registeredViewModes[viewMode].icon"/>
|
||||||
|
{{ $i18n.get('label_visualization') }}
|
||||||
<b-icon icon="menu-down" />
|
<b-icon icon="menu-down" />
|
||||||
</button>
|
</button>
|
||||||
<b-dropdown-item
|
<b-dropdown-item
|
||||||
|
@ -237,12 +236,70 @@
|
||||||
</b-dropdown>
|
</b-dropdown>
|
||||||
</b-field>
|
</b-field>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="!isOnTheme"
|
||||||
|
class="search-control-item">
|
||||||
|
<b-field>
|
||||||
|
<b-dropdown
|
||||||
|
v-model="adminViewMode"
|
||||||
|
:mobile-modal="false"
|
||||||
|
position="is-bottom-left"
|
||||||
|
:aria-label="$i18n.get('label_view_mode')">
|
||||||
|
<button
|
||||||
|
class="button is-white"
|
||||||
|
slot="trigger">
|
||||||
|
<span>
|
||||||
|
<b-icon
|
||||||
|
:icon="(adminViewMode == 'table' || adminViewMode == undefined) ?
|
||||||
|
'table' : (adminViewMode == 'cards' ?
|
||||||
|
'view-list' : 'view-grid')"/>
|
||||||
|
</span>
|
||||||
|
{{ $i18n.get('label_visualization') }}
|
||||||
|
<b-icon icon="menu-down" />
|
||||||
|
</button>
|
||||||
|
<b-dropdown-item :value="'table'">
|
||||||
|
<b-icon icon="table"/>
|
||||||
|
{{ $i18n.get('label_table') }}
|
||||||
|
</b-dropdown-item>
|
||||||
|
<b-dropdown-item :value="'cards'">
|
||||||
|
<b-icon icon="view-list"/>
|
||||||
|
{{ $i18n.get('label_cards') }}
|
||||||
|
</b-dropdown-item>
|
||||||
|
<b-dropdown-item :value="'grid'">
|
||||||
|
<b-icon icon="view-grid"/>
|
||||||
|
{{ $i18n.get('label_grid') }}
|
||||||
|
</b-dropdown-item>
|
||||||
|
</b-dropdown>
|
||||||
|
</b-field>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ADVANCED SEARCH -->
|
||||||
|
<div
|
||||||
|
v-if="openAdvancedSearch">
|
||||||
|
<div class="columns tnc-advanced-search-close">
|
||||||
|
<div class="column">
|
||||||
|
<button
|
||||||
|
@click="openAdvancedSearch = false"
|
||||||
|
class="button is-white is-pulled-right">
|
||||||
|
<b-icon
|
||||||
|
size="is-small"
|
||||||
|
icon="close"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<advanced-search
|
||||||
|
:is-repository-level="isRepositoryLevel"
|
||||||
|
:metadata-list="fields" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- --------------- -->
|
||||||
|
|
||||||
<!-- STATUS TABS, only on Admin -------- -->
|
<!-- STATUS TABS, only on Admin -------- -->
|
||||||
<div
|
<div
|
||||||
v-if="!isOnTheme"
|
v-if="!isOnTheme && !openAdvancedSearch"
|
||||||
class="tabs">
|
class="tabs">
|
||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
|
@ -269,7 +326,8 @@
|
||||||
:table-fields="tableFields"
|
:table-fields="tableFields"
|
||||||
:items="items"
|
:items="items"
|
||||||
:is-loading="isLoadingItems"
|
:is-loading="isLoadingItems"
|
||||||
:is-on-trash="status == 'trash'"/>
|
:is-on-trash="status == 'trash'"
|
||||||
|
:view-mode="adminViewMode"/>
|
||||||
|
|
||||||
<!-- Theme View Modes -->
|
<!-- Theme View Modes -->
|
||||||
<div
|
<div
|
||||||
|
@ -326,6 +384,7 @@
|
||||||
import ItemsList from '../../components/lists/items-list.vue';
|
import ItemsList from '../../components/lists/items-list.vue';
|
||||||
import FiltersItemsList from '../../components/search/filters-items-list.vue';
|
import FiltersItemsList from '../../components/search/filters-items-list.vue';
|
||||||
import Pagination from '../../components/search/pagination.vue'
|
import Pagination from '../../components/search/pagination.vue'
|
||||||
|
import AdvancedSearch from '../../components/advanced-search/advanced-search.vue';
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -345,7 +404,9 @@
|
||||||
futureSearchQuery: '',
|
futureSearchQuery: '',
|
||||||
isHeaderShrinked: false,
|
isHeaderShrinked: false,
|
||||||
localTableFields: [],
|
localTableFields: [],
|
||||||
registeredViewModes: tainacan_plugin.registered_view_modes
|
registeredViewModes: tainacan_plugin.registered_view_modes,
|
||||||
|
adminViewMode: 'table',
|
||||||
|
openAdvancedSearch: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -388,7 +449,8 @@
|
||||||
components: {
|
components: {
|
||||||
ItemsList,
|
ItemsList,
|
||||||
FiltersItemsList,
|
FiltersItemsList,
|
||||||
Pagination
|
Pagination,
|
||||||
|
AdvancedSearch,
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
tableFields() {
|
tableFields() {
|
||||||
|
@ -447,11 +509,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let thumbnailField = this.localTableFields.find(field => field.slug == 'thumbnail');
|
||||||
|
let creationDateField = this.localTableFields.find(field => field.slug == 'creation_date');
|
||||||
|
let authorNameField = this.localTableFields.find(field => field.slug == 'author_name');
|
||||||
|
|
||||||
this.$eventBusSearch.addFetchOnly({
|
this.$eventBusSearch.addFetchOnly({
|
||||||
'0': 'thumbnail',
|
'0': thumbnailField.display ? 'thumbnail' : null,
|
||||||
'meta': fetchOnlyFieldIds,
|
'meta': fetchOnlyFieldIds,
|
||||||
'1': 'creation_date',
|
'1': creationDateField.display ? 'creation_date' : null,
|
||||||
'2': 'author_name'
|
'2': authorNameField.display ? 'author_name': null
|
||||||
});
|
});
|
||||||
this.$refs.displayedFieldsDropdown.toggle();
|
this.$refs.displayedFieldsDropdown.toggle();
|
||||||
},
|
},
|
||||||
|
@ -469,8 +535,8 @@
|
||||||
.catch(() => this.isLoadingFilters = false);
|
.catch(() => this.isLoadingFilters = false);
|
||||||
|
|
||||||
this.isLoadingFields = true;
|
this.isLoadingFields = true;
|
||||||
this.tableFields = [];
|
// Processing is done inside a local variable
|
||||||
|
let fields = [];
|
||||||
this.fetchFields({
|
this.fetchFields({
|
||||||
collectionId: this.collectionId,
|
collectionId: this.collectionId,
|
||||||
isRepositoryLevel: this.isRepositoryLevel,
|
isRepositoryLevel: this.isRepositoryLevel,
|
||||||
|
@ -478,7 +544,7 @@
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
||||||
this.tableFields.push({
|
fields.push({
|
||||||
name: this.$i18n.get('label_thumbnail'),
|
name: this.$i18n.get('label_thumbnail'),
|
||||||
field: 'row_thumbnail',
|
field: 'row_thumbnail',
|
||||||
field_type: undefined,
|
field_type: undefined,
|
||||||
|
@ -499,7 +565,7 @@
|
||||||
else if (field.display == 'yes')
|
else if (field.display == 'yes')
|
||||||
display = true;
|
display = true;
|
||||||
|
|
||||||
this.tableFields.push(
|
fields.push(
|
||||||
{
|
{
|
||||||
name: field.name,
|
name: field.name,
|
||||||
field: field.description,
|
field: field.description,
|
||||||
|
@ -515,7 +581,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tableFields.push({
|
fields.push({
|
||||||
name: this.$i18n.get('label_creation_date'),
|
name: this.$i18n.get('label_creation_date'),
|
||||||
field: 'row_creation',
|
field: 'row_creation',
|
||||||
field_type: undefined,
|
field_type: undefined,
|
||||||
|
@ -523,7 +589,7 @@
|
||||||
id: undefined,
|
id: undefined,
|
||||||
display: true
|
display: true
|
||||||
});
|
});
|
||||||
this.tableFields.push({
|
fields.push({
|
||||||
name: this.$i18n.get('label_created_by'),
|
name: this.$i18n.get('label_created_by'),
|
||||||
field: 'row_author',
|
field: 'row_author',
|
||||||
field_type: undefined,
|
field_type: undefined,
|
||||||
|
@ -547,7 +613,7 @@
|
||||||
'2': 'author_name'
|
'2': 'author_name'
|
||||||
});
|
});
|
||||||
this.isLoadingFields = false;
|
this.isLoadingFields = false;
|
||||||
|
this.tableFields = fields;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.isLoadingFields = false;
|
this.isLoadingFields = false;
|
||||||
|
@ -574,13 +640,16 @@
|
||||||
/* This condition is to prevent a incorrect fetch by filter or fields when we come from items
|
/* This condition is to prevent a incorrect fetch by filter or fields when we come from items
|
||||||
* at collection level to items page at repository level
|
* at collection level to items page at repository level
|
||||||
*/
|
*/
|
||||||
if(this.collectionId === to.params.collectionId) {
|
if (this.collectionId === to.params.collectionId) {
|
||||||
this.prepareFieldsAndFilters();
|
this.prepareFieldsAndFilters();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$eventBusSearch.setViewMode(this.defaultViewMode);
|
this.$eventBusSearch.setViewMode(this.defaultViewMode);
|
||||||
|
|
||||||
|
if(this.$route.query.openAdvancedSearch) {
|
||||||
|
this.openAdvancedSearch = this.$route.query.openAdvancedSearch;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
||||||
|
@ -602,6 +671,16 @@
|
||||||
|
|
||||||
@import '../../scss/_variables.scss';
|
@import '../../scss/_variables.scss';
|
||||||
|
|
||||||
|
.tnc-advanced-search-close {
|
||||||
|
padding-top: 47px;
|
||||||
|
padding-right: $page-side-padding;
|
||||||
|
padding-left: $page-side-padding;
|
||||||
|
|
||||||
|
.column {
|
||||||
|
padding: 0 0.3rem 0.3rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.page-container {
|
.page-container {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
@ -627,12 +706,27 @@
|
||||||
margin-top: 48px;
|
margin-top: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#collection-search-button {
|
.search-area {
|
||||||
border-radius: 0 !important;
|
display: flex;
|
||||||
padding: 0 8px !important;
|
align-items: center;
|
||||||
border-color: $tainacan-input-background;
|
width: 100%;
|
||||||
&:focus, &:active {
|
|
||||||
border-color: none !important;
|
.control {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
input {
|
||||||
|
height: 27px;
|
||||||
|
font-size: 11px;
|
||||||
|
color: $gray-light;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
pointer-events: all;
|
||||||
|
cursor: pointer;
|
||||||
|
color: $tertiary;
|
||||||
|
height: 27px;
|
||||||
|
font-size: 18px !important;
|
||||||
|
}
|
||||||
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,6 +735,11 @@
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.filter-menu-compress-button-top-repo {
|
.filter-menu-compress-button-top-repo {
|
||||||
top: 123px !important;
|
top: 123px !important;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.b-checkbox.checkbox {
|
.b-checkbox.checkbox {
|
||||||
|
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,20 @@
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
|
min-width: 6rem;
|
||||||
.dropdown-content {
|
.dropdown-content {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border-radius: 0px !important;
|
border-radius: 0px !important;
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
padding: 0.375rem 1rem;
|
padding: 0.375rem 1rem;
|
||||||
|
font-size: 13px;
|
||||||
|
color: $tainacan-input-color !important;
|
||||||
label { margin-bottom: 0; }
|
label { margin-bottom: 0; }
|
||||||
&.control { font-size: 13px !important; }
|
&.control { font-size: 13px !important; }
|
||||||
.b-checkbox { width: 100% };
|
.b-checkbox { width: 100% };
|
||||||
&:hover { background-color: $primary-lighter; }
|
&:hover { background-color: $primary-lighter; }
|
||||||
.is-small { color: gray; }
|
.is-small { color: gray; }
|
||||||
|
&.is-active { background-color: white; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
// Tainacan modals
|
// Tainacan modals
|
||||||
.tainacan-modal-title {
|
.tainacan-modal-title {
|
||||||
h1, h2 {
|
h1, h2 {
|
||||||
|
@ -35,9 +34,74 @@
|
||||||
padding: 80px 0em 0.4em 0em !important;
|
padding: 80px 0em 0.4em 0em !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Bulma modals customized for Tainacan
|
||||||
|
.dialog{
|
||||||
|
.modal-background {
|
||||||
|
background-color: rgba(0, 0, 0, 0.70);
|
||||||
|
}
|
||||||
|
.modal-card {
|
||||||
|
background-color: $modal-backgound-color;
|
||||||
|
color: $secondary;
|
||||||
|
border-radius: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 35px;
|
||||||
|
margin: 0 auto !important;
|
||||||
|
|
||||||
.modal-background {
|
.modal-card-head, .modal-card-body, .modal-card-foot {
|
||||||
background-color: rgba(0, 0, 0, 0.70);
|
background-color: $modal-backgound-color;
|
||||||
|
color: $secondary;
|
||||||
|
border: none;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
.modal-custom-icon {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 50px;
|
||||||
|
height: 80px;
|
||||||
|
width: 80px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.modal-card-head {
|
||||||
|
h1 {
|
||||||
|
color: $secondary;
|
||||||
|
}
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.modal-card-body {
|
||||||
|
padding: 0px 0px 0px 16px;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
.modal-card-foot {
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 24px 0px 0px 0px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
border-radius: 6px !important;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 2px 15px !important;
|
||||||
|
margin-top: 0px !important;
|
||||||
|
margin-bottom: 0px !important;
|
||||||
|
height: inherit !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
display: inline-flex !important;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px !important;
|
||||||
|
}
|
||||||
|
.button.is-success {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.button:not(.is-success) {
|
||||||
|
background-color: white;
|
||||||
|
color: $tertiary;
|
||||||
|
border: 1px solid $gray-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WordPress Media Modal customization
|
// WordPress Media Modal customization
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
border: 2px solid $gray-light;
|
border: 2px solid $gray-light;
|
||||||
width: 2.7em;
|
width: 2.7em;
|
||||||
height: 1.7em;
|
height: 1.7em;
|
||||||
|
transition: none;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
|
|
@ -23,17 +23,6 @@
|
||||||
top: auto;
|
top: auto;
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
|
|
||||||
&::before {
|
|
||||||
box-shadow: inset 50px 0 10px -12px #222;
|
|
||||||
content: " ";
|
|
||||||
width: 50px;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
label.checkbox {
|
label.checkbox {
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -141,7 +130,7 @@
|
||||||
&.selected-row {
|
&.selected-row {
|
||||||
background-color: $primary-lighter;
|
background-color: $primary-lighter;
|
||||||
.checkbox-cell .checkbox, .actions-cell .actions-container {
|
.checkbox-cell .checkbox, .actions-cell .actions-container {
|
||||||
background-color: $primary-lighter;
|
background-color: $primary-lighter-hover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
td {
|
td {
|
||||||
|
@ -172,20 +161,23 @@
|
||||||
width: 80px;
|
width: 80px;
|
||||||
|
|
||||||
.actions-container {
|
.actions-container {
|
||||||
visibility: hidden;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
background-color: transparent;
|
background-color: white;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
font-size: 18px !important;
|
font-size: 18px !important;
|
||||||
|
|
||||||
|
.mdi-settings, .mdi-settings::before {
|
||||||
|
font-size: 23px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -197,27 +189,15 @@
|
||||||
.checkbox-cell {
|
.checkbox-cell {
|
||||||
position: sticky !important;
|
position: sticky !important;
|
||||||
position: -webkit-sticky !important;
|
position: -webkit-sticky !important;
|
||||||
|
background-color: $gray-hover;
|
||||||
&::before { visibility: visible; }
|
|
||||||
|
|
||||||
.checkbox {
|
.checkbox {
|
||||||
background-color: $tainacan-input-background !important;
|
background-color: $gray-hover !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.actions-cell {
|
.actions-cell {
|
||||||
.actions-container {
|
.actions-container {
|
||||||
visibility: visible;
|
background: $gray-hover !important;
|
||||||
background: $tainacan-input-background !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
box-shadow: inset -97px 0 17px -21px #222;
|
|
||||||
content: " ";
|
|
||||||
width: 100px;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
right: 0px;
|
|
||||||
top: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
.form-submit {
|
.form-submit {
|
||||||
justify-content: space-between !important;
|
justify-content: space-between !important;
|
||||||
padding: 12px 30px;
|
padding: 12px 0px ;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
.button {
|
.button {
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.required-field-asterisk {
|
.required-field-asterisk {
|
||||||
color: $gray;
|
color: $gray;
|
||||||
|
@ -26,8 +27,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.input, .textarea {
|
.input, .textarea {
|
||||||
|
background-color: white;
|
||||||
background-color: $tainacan-input-background;
|
border: 1px solid $tainacan-input-background;
|
||||||
color: $tainacan-input-color;
|
color: $tainacan-input-color;
|
||||||
transition: background-color 0.1s;
|
transition: background-color 0.1s;
|
||||||
|
|
||||||
|
@ -54,7 +55,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.radio, .checkbox {
|
.radio, .checkbox {
|
||||||
margin-bottom: 0.2em;
|
margin-bottom: 5px;
|
||||||
|
align-items: baseline;
|
||||||
|
|
||||||
&.is-danger {
|
&.is-danger {
|
||||||
border-color: $danger;
|
border-color: $danger;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +78,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.is-empty select{
|
&.is-empty select{
|
||||||
background-color: $tainacan-input-background !important;
|
//background-color: $tainacan-input-background !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.dropdown {
|
.dropdown {
|
||||||
|
|
|
@ -12,17 +12,20 @@ $tertiary-invert: findColorInvert($tertiary);
|
||||||
|
|
||||||
$primary-light:#c1dae0;
|
$primary-light:#c1dae0;
|
||||||
$primary-lighter: #e6f6f8;
|
$primary-lighter: #e6f6f8;
|
||||||
|
$primary-lighter-hover: #d1e6e6;
|
||||||
$primary-dark: #55A0AF;
|
$primary-dark: #55A0AF;
|
||||||
$primary-darker: darken($primary-dark, 5%);
|
$primary-darker: darken($primary-dark, 5%);
|
||||||
|
|
||||||
$success: #25a189;
|
$success: #25a189;
|
||||||
$success-invert: findColorInvert($success);
|
$success-invert: findColorInvert($success);
|
||||||
|
|
||||||
|
$modal-backgound-color: #bfd8dd;
|
||||||
$separator-color: #2b98a4;
|
$separator-color: #2b98a4;
|
||||||
$tainacan-input-color: #1d1d1d;
|
$tainacan-input-color: #1d1d1d;
|
||||||
$tainacan-input-background: #e5e5e5;
|
$tainacan-input-background: #e5e5e5;
|
||||||
$tainacan-placeholder-color: #898d8f;
|
$tainacan-placeholder-color: #898d8f;
|
||||||
$draggable-border-color: #d8d8d8;
|
$draggable-border-color: #d8d8d8;
|
||||||
|
$gray-hover: #dcdcdc;
|
||||||
|
|
||||||
$gray: #b1b1b1;
|
$gray: #b1b1b1;
|
||||||
$gray-invert: findColorInvert($gray);
|
$gray-invert: findColorInvert($gray);
|
||||||
|
@ -62,6 +65,7 @@ $header-height: 53px;
|
||||||
$subheader-height: 82px;
|
$subheader-height: 82px;
|
||||||
$side-menu-width: 180px;
|
$side-menu-width: 180px;
|
||||||
$filter-menu-width: 200px;
|
$filter-menu-width: 200px;
|
||||||
|
$filter-menu-width-theme: 270px;
|
||||||
$page-height: calc(100% - 53px);
|
$page-height: calc(100% - 53px);
|
||||||
|
|
||||||
// Overall Pages padding:
|
// Overall Pages padding:
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
.tainacan-cards-container {
|
||||||
|
min-height: 200px;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.selected-card {
|
||||||
|
background-color: $primary-lighter;
|
||||||
|
.metadata-title {
|
||||||
|
background-color: $primary-lighter-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tainacan-card {
|
||||||
|
padding: 0px;
|
||||||
|
flex-basis: 0;
|
||||||
|
margin: 0.75rem;
|
||||||
|
max-width: 410px;
|
||||||
|
min-width: 410px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $tainacan-input-background !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-checkbox {
|
||||||
|
position: absolute;
|
||||||
|
margin-left: 1.0rem;
|
||||||
|
margin-top: 9px;
|
||||||
|
}
|
||||||
|
.actions-area {
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
top: -7px;
|
||||||
|
padding-right: 12px;
|
||||||
|
width: 80px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transition: visibility 0.2s, opacity 0.2s;
|
||||||
|
}
|
||||||
|
&:hover .actions-area {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-line {
|
||||||
|
height: 1px;
|
||||||
|
background-color: $tainacan-input-background;
|
||||||
|
margin-left: -44px;
|
||||||
|
margin-right: -44px;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 170px;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
&:hover img {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata-title {
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
padding: 0.75rem 2.75rem;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: -27px;
|
||||||
|
}
|
||||||
|
&:hover .metadata-title {
|
||||||
|
background-color: $gray-hover !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media {
|
||||||
|
margin-bottom: -6px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.list-metadata {
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
flex: 1;
|
||||||
|
font-size: 0.6875rem;
|
||||||
|
color: gray;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.metadata-label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.0;
|
||||||
|
margin-bottom: 0.2rem;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $gray-light;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata-value {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
.tainacan-grid-container {
|
||||||
|
min-height: 200px;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.selected-grid-item {
|
||||||
|
background-color: $primary-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tainacan-grid-item {
|
||||||
|
max-width: 258px;
|
||||||
|
flex-basis: 0;
|
||||||
|
margin: 1rem 1.5rem 1.5rem 1.5rem;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $tainacan-input-background;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-item-checkbox {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 9px;
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
.actions-area {
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
padding: 8px;
|
||||||
|
transition: visibility 0.2s, opacity 0.2s;
|
||||||
|
margin-top: -43px;
|
||||||
|
background-color: $tainacan-input-background;
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover .actions-area {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
&.selected-grid-item {
|
||||||
|
.actions-area {
|
||||||
|
background-color: $primary-lighter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
min-width: 258px;
|
||||||
|
max-width: 258px;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 2px;
|
||||||
|
margin-bottom: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.metadata-title {
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
margin-top: 6px;
|
||||||
|
margin-right: 6px;
|
||||||
|
margin-left: 24px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: left;
|
||||||
|
padding: 6px 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return apply_filters('tainacan-admin-i18n', [
|
||||||
// Tainacan common terms
|
// Tainacan common terms
|
||||||
'repository' => __( 'Repository', 'tainacan' ),
|
'repository' => __( 'Repository', 'tainacan' ),
|
||||||
'collections' => __( 'Collections', 'tainacan' ),
|
'collections' => __( 'Collections', 'tainacan' ),
|
||||||
|
@ -40,8 +40,12 @@ return [
|
||||||
'add_one_item' => __( 'Add one item', 'tainacan' ),
|
'add_one_item' => __( 'Add one item', 'tainacan' ),
|
||||||
'add_items_bulk' => __( 'Add items in bulk', 'tainacan' ),
|
'add_items_bulk' => __( 'Add items in bulk', 'tainacan' ),
|
||||||
'add_items_external_source' => __( 'Add items from an external source', 'tainacan' ),
|
'add_items_external_source' => __( 'Add items from an external source', 'tainacan' ),
|
||||||
|
'new_mapped_item' => __( 'New mapped collection', 'tainacan' ),
|
||||||
|
'new_blank_collection' => __( 'New Blank Collection', 'tainacan' ),
|
||||||
'split' => __( 'Split', 'tainacan' ),
|
'split' => __( 'Split', 'tainacan' ),
|
||||||
'unified' => __( 'Unified', 'tainacan' ),
|
'unified' => __( 'Unified', 'tainacan' ),
|
||||||
|
'add_more_one_search_field' => __( 'Add more one search field', 'tainacan' ),
|
||||||
|
'clear_search' => __( 'Clear search', 'tainacan' ),
|
||||||
|
|
||||||
// Wordpress Status
|
// Wordpress Status
|
||||||
'publish' => __( 'Publish', 'tainacan' ),
|
'publish' => __( 'Publish', 'tainacan' ),
|
||||||
|
@ -121,7 +125,7 @@ return [
|
||||||
'label_available_filters' => __( 'Available Filters', 'tainacan' ),
|
'label_available_filters' => __( 'Available Filters', 'tainacan' ),
|
||||||
'label_available_filter_types' => __( 'Available Filter Types', 'tainacan' ),
|
'label_available_filter_types' => __( 'Available Filter Types', 'tainacan' ),
|
||||||
'label_per_page' => __( 'per Page', 'tainacan' ),
|
'label_per_page' => __( 'per Page', 'tainacan' ),
|
||||||
'label_table_fields' => __( 'Metadata on table', 'tainacan' ),
|
'label_displayed_metadata' => __( 'Displayed metadata', 'tainacan' ),
|
||||||
'label_required' => __( 'Required', 'tainacan' ),
|
'label_required' => __( 'Required', 'tainacan' ),
|
||||||
'label_allow_multiple' => __( 'Allow multiple values', 'tainacan' ),
|
'label_allow_multiple' => __( 'Allow multiple values', 'tainacan' ),
|
||||||
'label_default_value' => __( 'Default value', 'tainacan' ),
|
'label_default_value' => __( 'Default value', 'tainacan' ),
|
||||||
|
@ -197,6 +201,12 @@ return [
|
||||||
'label_default_view_mode' => __( 'Default view mode', 'tainacan' ),
|
'label_default_view_mode' => __( 'Default view mode', 'tainacan' ),
|
||||||
'label_enabled_view_modes' => __( 'Enabled view modes', 'tainacan' ),
|
'label_enabled_view_modes' => __( 'Enabled view modes', 'tainacan' ),
|
||||||
'label_view_modes_available' => __( 'View modes available on theme', 'tainacan' ),
|
'label_view_modes_available' => __( 'View modes available on theme', 'tainacan' ),
|
||||||
|
'label_warning' => __( 'Warning', 'tainacan' ),
|
||||||
|
'label_error' => __( 'Erro', 'tainacan' ),
|
||||||
|
'label_grid' => __( 'Grid', 'tainacan' ),
|
||||||
|
'label_table' => __( 'Table', 'tainacan' ),
|
||||||
|
'label_cards' => __( 'Cards', 'tainacan' ),
|
||||||
|
'label_visualization' => __( 'Visualization', 'tainacan' ),
|
||||||
|
|
||||||
// Instructions. More complex sentences to guide user and placeholders
|
// Instructions. More complex sentences to guide user and placeholders
|
||||||
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
|
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
|
||||||
|
@ -218,6 +228,7 @@ return [
|
||||||
'instruction_insert_url' => __( 'Insert URL', 'tainacan' ),
|
'instruction_insert_url' => __( 'Insert URL', 'tainacan' ),
|
||||||
'instruction_write_text' => __( 'Write Text', 'tainacan' ),
|
'instruction_write_text' => __( 'Write Text', 'tainacan' ),
|
||||||
'instruction_search' => __( 'Search', 'tainacan' ),
|
'instruction_search' => __( 'Search', 'tainacan' ),
|
||||||
|
'instruction_search_on_repository' => __( 'Search on repository', 'tainacan' ),
|
||||||
|
|
||||||
// Info. Other feedback to user.
|
// Info. Other feedback to user.
|
||||||
'info_name_is_required' => __( 'Name is required.', 'tainacan' ),
|
'info_name_is_required' => __( 'Name is required.', 'tainacan' ),
|
||||||
|
@ -303,5 +314,5 @@ return [
|
||||||
'tainacan-filter-category-taginput' => __( 'Taxonomy Tag Input', 'tainacan' ),
|
'tainacan-filter-category-taginput' => __( 'Taxonomy Tag Input', 'tainacan' ),
|
||||||
'tainacan-filter-category-checkbox' => __( 'Taxonomy Check Box', 'tainacan' ),
|
'tainacan-filter-category-checkbox' => __( 'Taxonomy Check Box', 'tainacan' ),
|
||||||
'tainacan-filter-category-selectbox' => __( 'Taxonomy Select Box', 'tainacan' )
|
'tainacan-filter-category-selectbox' => __( 'Taxonomy Select Box', 'tainacan' )
|
||||||
]
|
]);
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -96,16 +96,11 @@ export default {
|
||||||
line-height: 20px !important;
|
line-height: 20px !important;
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
}
|
}
|
||||||
#collection-search-button {
|
|
||||||
border: 1px solid $secondary !important;
|
|
||||||
height: 32px !important;
|
|
||||||
background-color: $secondary;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.input, .textarea {
|
.input, .textarea {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border: none;
|
border: 1px solid $tainacan-input-background;
|
||||||
border-radius: 1px !important;
|
border-radius: 1px !important;
|
||||||
|
background-color: white;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
|
||||||
&:focus, &:active {
|
&:focus, &:active {
|
||||||
|
@ -123,6 +118,8 @@ export default {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.b-checkbox.checkbox {
|
.b-checkbox.checkbox {
|
||||||
|
align-items: baseline;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
@ -272,7 +269,6 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.select select{
|
.select select{
|
||||||
border: none;
|
|
||||||
border-radius: 1;
|
border-radius: 1;
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
color: #1d1d1d;
|
color: #1d1d1d;
|
||||||
|
@ -288,9 +284,19 @@ export default {
|
||||||
|
|
||||||
.filters-menu {
|
.filters-menu {
|
||||||
height: auto;
|
height: auto;
|
||||||
min-width: $filter-menu-width;
|
min-width: $filter-menu-width-theme;
|
||||||
background-color: unset;
|
background-color: unset;
|
||||||
border-right: 1px solid $tainacan-input-background;
|
border-right: 0;
|
||||||
|
padding: 25px 25px 25px 4.1666667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-control {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
padding-left: 4.166666667%;
|
||||||
|
padding-right: 4.166666667%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#items-list-area {
|
#items-list-area {
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Tainacan\API\EndPoints;
|
||||||
use \Tainacan\API\REST_Controller;
|
use \Tainacan\API\REST_Controller;
|
||||||
use Tainacan\Repositories;
|
use Tainacan\Repositories;
|
||||||
use Tainacan\Entities;
|
use Tainacan\Entities;
|
||||||
|
use Tainacan\Entities\Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the Collections REST Controller
|
* Represents the Collections REST Controller
|
||||||
|
@ -249,6 +250,8 @@ class REST_Collections_Controller extends REST_Controller {
|
||||||
'collection' => $body
|
'collection' => $body
|
||||||
], 400);
|
], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->collection = new Collection();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$prepared_post = $this->prepare_item_for_database( $body );
|
$prepared_post = $this->prepare_item_for_database( $body );
|
||||||
|
@ -280,7 +283,8 @@ class REST_Collections_Controller extends REST_Controller {
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function create_item_permissions_check( $request ) {
|
public function create_item_permissions_check( $request ) {
|
||||||
return $this->collection->can_edit();
|
$dummy = new Entities\Collection();
|
||||||
|
return current_user_can($dummy->get_capabilities()->edit_posts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -294,7 +298,7 @@ class REST_Collections_Controller extends REST_Controller {
|
||||||
|
|
||||||
foreach ($request as $key => $value){
|
foreach ($request as $key => $value){
|
||||||
$set_ = 'set_' . $key;
|
$set_ = 'set_' . $key;
|
||||||
$this->collection->$set_($value);
|
if(method_exists($this->collection, $set_)) $this->collection->$set_($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->collection;
|
return $this->collection;
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Tainacan\API\EndPoints;
|
||||||
use \Tainacan\API\REST_Controller;
|
use \Tainacan\API\REST_Controller;
|
||||||
use Tainacan\Entities;
|
use Tainacan\Entities;
|
||||||
use Tainacan\Repositories;
|
use Tainacan\Repositories;
|
||||||
|
use Tainacan\Entities\Entity;
|
||||||
|
|
||||||
class REST_Export_Controller extends REST_Controller {
|
class REST_Export_Controller extends REST_Controller {
|
||||||
private $item_metadata_repository;
|
private $item_metadata_repository;
|
||||||
|
@ -126,7 +127,7 @@ class REST_Export_Controller extends REST_Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Tainacan\Entities\Entity $item
|
* @param \Tainacan\Entities\Item $item
|
||||||
* @param \WP_REST_Request $request
|
* @param \WP_REST_Request $request
|
||||||
*
|
*
|
||||||
* @return array|\WP_Error|\WP_REST_Response
|
* @return array|\WP_Error|\WP_REST_Response
|
||||||
|
@ -142,6 +143,118 @@ class REST_Export_Controller extends REST_Controller {
|
||||||
|
|
||||||
return $prepared_item;
|
return $prepared_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param \WP_REST_Request $request
|
||||||
|
* @param \WP_Query|Entities\Item $query
|
||||||
|
* @param array $args
|
||||||
|
* @return \WP_Error|number
|
||||||
|
*/
|
||||||
|
public function export($request, $query, $args) {
|
||||||
|
|
||||||
|
$type = \Tainacan\Exposers\Exposers::request_has_type($request);
|
||||||
|
$path = wp_upload_dir();
|
||||||
|
$path = $path['path'];
|
||||||
|
$filename = $path.date('YmdHis').'-tainacan-export.'.$type->get_extension();
|
||||||
|
$pid = -1;
|
||||||
|
|
||||||
|
$log = \Tainacan\Entities\Log::create(
|
||||||
|
__('Export Process', 'tainacan'),
|
||||||
|
__('Exporting Data', 'tainacan').'\nArgs: '.print_r($args, true),
|
||||||
|
['file' => $filename],
|
||||||
|
[],
|
||||||
|
'processing'
|
||||||
|
);
|
||||||
|
|
||||||
|
$body = json_decode( $request->get_body(), true );
|
||||||
|
$background = ! (isset($body['export-background']) && $body['export-background'] == false);
|
||||||
|
if( $background ) {
|
||||||
|
$pid = pcntl_fork();
|
||||||
|
} else {
|
||||||
|
$pid = true;
|
||||||
|
}
|
||||||
|
if ($pid === -1) {
|
||||||
|
$error = new \WP_Error('could not fork');
|
||||||
|
$log = \Tainacan\Entities\Log::create(
|
||||||
|
__('Export Process Error', 'tainacan'),
|
||||||
|
__('Exporting Error', 'tainacan').'\\nArgs: '.print_r($args, true).'\\nError: could not fork',
|
||||||
|
$error,
|
||||||
|
[],
|
||||||
|
'error'
|
||||||
|
);
|
||||||
|
remove_filter( 'rest_request_after_callbacks', [\Tainacan\Exposers\Exposers::get_instance(), 'rest_request_after_callbacks'], 10, 3 ); //exposer mapping
|
||||||
|
remove_filter( 'tainacan-rest-response', [\Tainacan\Exposers\Exposers::get_instance(), 'rest_response'], 10, 2 ); // exposer types
|
||||||
|
return $log;
|
||||||
|
} elseif ($pid) { // we are the parent or run at foreground
|
||||||
|
try {
|
||||||
|
ignore_user_abort(true);
|
||||||
|
set_time_limit(0);
|
||||||
|
ini_set("memory_limit", "256M");
|
||||||
|
|
||||||
|
if($background) { // wait for child to respond and exit and reconnect database if is forked
|
||||||
|
$status = null;
|
||||||
|
pcntl_wait($status);
|
||||||
|
global $wpdb;
|
||||||
|
$wpdb->db_connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = [];
|
||||||
|
if(isset($request['collection_id'])) { // One Colletion
|
||||||
|
$collection_id = $request['collection_id'];
|
||||||
|
$items = $query;
|
||||||
|
if ($items->have_posts()) {
|
||||||
|
while ( $items->have_posts() ) { //TODO write line by line
|
||||||
|
$items->the_post();
|
||||||
|
|
||||||
|
$item = new Entities\Item($items->post);
|
||||||
|
|
||||||
|
$prepared_item = $this->prepare_item_for_response($item, $request);
|
||||||
|
|
||||||
|
array_push($response, $prepared_item);
|
||||||
|
file_put_contents('/tmp/2', print_r($prepared_item, true), FILE_APPEND);
|
||||||
|
}
|
||||||
|
wp_reset_postdata();
|
||||||
|
}
|
||||||
|
} elseif (isset($request['item_id'])) { // One Item
|
||||||
|
|
||||||
|
$item = new Entities\Item($request['item_id']);
|
||||||
|
if($item->get_id() > 0) {
|
||||||
|
$prepared_item = $this->prepare_item_for_response($item, $request);
|
||||||
|
|
||||||
|
$response = [$prepared_item];
|
||||||
|
}
|
||||||
|
} else { // Export All
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$rest_response = new \WP_REST_Response(apply_filters('tainacan-rest-response', $response, $request));
|
||||||
|
//file_put_contents($filename, $rest_response->get_data());
|
||||||
|
file_put_contents('/tmp/1', print_r($rest_response->get_data(), true));
|
||||||
|
|
||||||
|
if($background) {
|
||||||
|
$log->set_status('publish');
|
||||||
|
$logs = \Tainacan\Repositories\Logs::get_instance();
|
||||||
|
$logs->update($log);
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
return $rest_response->get_data();
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
if($background) {
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // we are the child
|
||||||
|
|
||||||
|
remove_filter( 'rest_request_after_callbacks', [\Tainacan\Exposers\Exposers::get_instance(), 'rest_request_after_callbacks'], 10, 3 ); //exposer mapping
|
||||||
|
remove_filter( 'tainacan-rest-response', [\Tainacan\Exposers\Exposers::get_instance(), 'rest_response'], 10, 2 ); // exposer types
|
||||||
|
return $log;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \WP_REST_Request $request
|
* @param \WP_REST_Request $request
|
||||||
|
@ -149,36 +262,38 @@ class REST_Export_Controller extends REST_Controller {
|
||||||
* @return \WP_Error|\WP_REST_Response
|
* @return \WP_Error|\WP_REST_Response
|
||||||
*/
|
*/
|
||||||
public function get_items( $request ) {
|
public function get_items( $request ) {
|
||||||
$args = $this->prepare_filters($request);
|
$args = $this->prepare_filters($request); // TODO default args
|
||||||
$rest_response = new \WP_REST_Response([], 200); // TODO error, empty response
|
$rest_response = new \WP_REST_Response([], 200); // TODO error, empty response
|
||||||
|
|
||||||
if(isset($request['collection_id'])) {
|
if(isset($request['collection_id'])) { // One Colletion
|
||||||
$collection_id = $request['collection_id'];
|
$collection_id = $request['collection_id'];
|
||||||
$items = $this->items_repository->fetch($args, $collection_id, 'WP_Query');
|
$items = $this->items_repository->fetch($args, $collection_id, 'WP_Query');
|
||||||
|
|
||||||
$response = [];
|
$response = $this->export($request, $items, $args);
|
||||||
if ($items->have_posts()) {
|
|
||||||
while ( $items->have_posts() ) {
|
|
||||||
$items->the_post();
|
|
||||||
|
|
||||||
$item = new Entities\Item($items->post);
|
|
||||||
|
|
||||||
$prepared_item = $this->prepare_item_for_response($item, $request);
|
|
||||||
|
|
||||||
array_push($response, $prepared_item);
|
|
||||||
}
|
|
||||||
|
|
||||||
wp_reset_postdata();
|
|
||||||
}
|
|
||||||
|
|
||||||
$total_items = $items->found_posts;
|
$total_items = $items->found_posts;
|
||||||
$max_pages = ceil($total_items / (int) $items->query_vars['posts_per_page']);
|
$ret = $response instanceof Entity ? $response->__toArray() : $response;
|
||||||
|
$rest_response = new \WP_REST_Response($ret, 200);
|
||||||
$rest_response = new \WP_REST_Response(apply_filters('tainacan-rest-response', $response, $request), 200);
|
|
||||||
|
|
||||||
$rest_response->header('X-WP-Total', (int) $total_items);
|
$rest_response->header('X-WP-Total', (int) $total_items);
|
||||||
$rest_response->header('X-WP-TotalPages', (int) $max_pages);
|
} elseif (isset($request['item_id'])) { // One Item
|
||||||
|
|
||||||
|
$item = new Entities\Item($request['item_id']);
|
||||||
|
if($item->get_id() > 0) {
|
||||||
|
$response = $this->export($request, $item, $args);
|
||||||
|
|
||||||
|
$total_items = 1;
|
||||||
|
$max_pages = 1;
|
||||||
|
|
||||||
|
$rest_response = new \WP_REST_Response($response->__toArray(), 200);
|
||||||
|
|
||||||
|
$rest_response->header('X-WP-Total', 1);
|
||||||
|
$rest_response->header('X-WP-TotalPages', 1);
|
||||||
|
}
|
||||||
|
} else { // Export All
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $rest_response;
|
return $rest_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tainacan\API\EndPoints;
|
||||||
|
|
||||||
|
use \Tainacan\API\REST_Controller;
|
||||||
|
|
||||||
|
class REST_Field_Mappers_Controller extends REST_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST_Field_Mappers_Controller constructor.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
$this->rest_base = 'field-mappers';
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route($this->namespace, '/' . $this->rest_base,
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'methods' => \WP_REST_Server::READABLE,
|
||||||
|
'callback' => array($this, 'get_items'),
|
||||||
|
'permission_callback' => array($this, 'get_items_permissions_check'),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Tainacan\Exposers\Mappers\Mapper $mapper
|
||||||
|
* @param \WP_REST_Request $request
|
||||||
|
*map
|
||||||
|
* @return mixed|\WP_Error|\WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $mapper, $request ) {
|
||||||
|
|
||||||
|
$field_arr = $mapper->_toArray();
|
||||||
|
|
||||||
|
return $field_arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \WP_REST_Request $request
|
||||||
|
*
|
||||||
|
* @return \WP_Error|\WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$Tainacan_Exposers = \Tainacan\Exposers\Exposers::get_instance();
|
||||||
|
|
||||||
|
$field_mappers = $Tainacan_Exposers->get_mappers( 'OBJECT' );
|
||||||
|
|
||||||
|
$prepared = [];
|
||||||
|
foreach ($field_mappers as $field_mapper){
|
||||||
|
array_push($prepared, $this->prepare_item_for_response($field_mapper, $request));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new \WP_REST_Response($prepared, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \WP_REST_Request $request
|
||||||
|
*
|
||||||
|
* @return bool|\WP_Error
|
||||||
|
*/
|
||||||
|
public function get_items_permissions_check( $request ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -327,7 +327,7 @@ class REST_Filters_Controller extends REST_Controller {
|
||||||
$item_arr['enabled'] = $item->get_enabled_for_collection();
|
$item_arr['enabled'] = $item->get_enabled_for_collection();
|
||||||
}
|
}
|
||||||
|
|
||||||
$item_arr['filter_type_object'] = $item->get_filter_type_object()->_toArray();
|
$item_arr['filter_type_object'] = $item->get_filter_type_object() ? $item->get_filter_type_object()->_toArray() : $item->get_filter_type_object();
|
||||||
|
|
||||||
return $item_arr;
|
return $item_arr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,8 @@ class REST_Items_Controller extends REST_Controller {
|
||||||
if ( isset($request['view_mode']) ) {
|
if ( isset($request['view_mode']) ) {
|
||||||
|
|
||||||
// TODO: Check if requested view mode is really enabled for current collection
|
// TODO: Check if requested view mode is really enabled for current collection
|
||||||
$view_mode = \Tainacan\Theme_Helper::get_instance()->get_view_mode($request['view_mode']);
|
$view_mode = \Tainacan\Theme_Helper::get_instance();
|
||||||
|
$view_mode = $view_mode->get_view_mode($request['view_mode']);
|
||||||
|
|
||||||
if ($view_mode && $view_mode['type'] == 'template' && isset($view_mode['template']) && file_exists($view_mode['template'])) {
|
if ($view_mode && $view_mode['type'] == 'template' && isset($view_mode['template']) && file_exists($view_mode['template'])) {
|
||||||
$return_template = true;
|
$return_template = true;
|
||||||
|
|
|
@ -14,6 +14,7 @@ $rest_logs_controller = new \Tainacan\API\EndPoints\REST_Logs_Controlle
|
||||||
$rest_field_types_controller = new \Tainacan\API\EndPoints\REST_Field_Types_Controller();
|
$rest_field_types_controller = new \Tainacan\API\EndPoints\REST_Field_Types_Controller();
|
||||||
$rest_filter_types_controller = new \Tainacan\API\EndPoints\REST_Filter_Types_Controller();
|
$rest_filter_types_controller = new \Tainacan\API\EndPoints\REST_Filter_Types_Controller();
|
||||||
new \Tainacan\API\EndPoints\REST_Export_Controller();
|
new \Tainacan\API\EndPoints\REST_Export_Controller();
|
||||||
|
new \Tainacan\API\EndPoints\REST_Field_Mappers_Controller();
|
||||||
// Add here other endpoints imports
|
// Add here other endpoints imports
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -0,0 +1,258 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tainacan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract Tainacan_Background_Process class.
|
||||||
|
*
|
||||||
|
* Uses https://github.com/A5hleyRich/wp-background-processing to handle DB
|
||||||
|
* updates in the background.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/Classes
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
if ( ! class_exists( 'WP_Async_Request', false ) ) {
|
||||||
|
include_once TAINACAN_CLASSES_DIR . '/lib/wp-async-request.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! class_exists( 'WP_Background_Process', false ) ) {
|
||||||
|
include_once TAINACAN_CLASSES_DIR . '/lib/wp-background-process.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tainacan_Background_Process class.
|
||||||
|
*/
|
||||||
|
abstract class Background_Process extends \WP_Background_Process {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table name where the queue is stored
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $table = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix
|
||||||
|
*
|
||||||
|
* (default value: 'wp')
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $prefix = 'tnc-bg';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action
|
||||||
|
*
|
||||||
|
* (default value: 'background_process')
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $action = 'process';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate new background process
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
global $wpdb;
|
||||||
|
$this->table = $wpdb->prefix . 'tnc_bg_process';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save queue
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function save($priority = 10) {
|
||||||
|
|
||||||
|
if ( ! empty( $this->data ) ) {
|
||||||
|
global $wpdb;
|
||||||
|
$wpdb->insert(
|
||||||
|
$this->table,
|
||||||
|
[
|
||||||
|
'data' => maybe_serialize($this->data),
|
||||||
|
'user_id' => get_current_user_id(),
|
||||||
|
'priority' => $priority,
|
||||||
|
'action' => $this->action,
|
||||||
|
'queued_on' => date('Y-m-d H:i:s')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update queue
|
||||||
|
*
|
||||||
|
* @param string $key Key.
|
||||||
|
* @param array $data Data.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function update( $key, $data ) {
|
||||||
|
if ( ! empty( $data ) ) {
|
||||||
|
global $wpdb;
|
||||||
|
$wpdb->update(
|
||||||
|
$this->table,
|
||||||
|
[
|
||||||
|
'data' => maybe_serialize($data),
|
||||||
|
'processed_last' => date('Y-m-d H:i:s')
|
||||||
|
],
|
||||||
|
['ID' => $key]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a process as done
|
||||||
|
*
|
||||||
|
* @param string $key Key.
|
||||||
|
* @param array $data Data.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function close( $key ) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$wpdb->update(
|
||||||
|
$this->table,
|
||||||
|
['done' => 1],
|
||||||
|
['ID' => $key],
|
||||||
|
['%d']
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete queue
|
||||||
|
*
|
||||||
|
* @param string $key Key.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function delete( $key ) {
|
||||||
|
global $wpdb;
|
||||||
|
$wpdb->delete(
|
||||||
|
$this->table,
|
||||||
|
['ID' => $key]
|
||||||
|
);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is queue empty
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function is_queue_empty() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$table = $this->table;
|
||||||
|
|
||||||
|
$count = $wpdb->get_var( $wpdb->prepare( "
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM {$table}
|
||||||
|
WHERE action = %s AND
|
||||||
|
done = false
|
||||||
|
", $this->action ) );
|
||||||
|
|
||||||
|
return ( $count > 0 ) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get batch
|
||||||
|
*
|
||||||
|
* @return stdClass Return the first batch from the queue
|
||||||
|
*/
|
||||||
|
protected function get_batch() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$table = $this->table;
|
||||||
|
|
||||||
|
$query = $wpdb->get_row( $wpdb->prepare( "
|
||||||
|
SELECT *
|
||||||
|
FROM {$table}
|
||||||
|
WHERE action = %s
|
||||||
|
AND done = FALSE
|
||||||
|
ORDER BY priority DESC, queued_on ASC
|
||||||
|
LIMIT 1
|
||||||
|
", $this->action ) );
|
||||||
|
|
||||||
|
$batch = new \stdClass();
|
||||||
|
$batch->key = $query->ID;
|
||||||
|
$batch->data = maybe_unserialize( $query->data );
|
||||||
|
|
||||||
|
return $batch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle
|
||||||
|
*
|
||||||
|
* Pass each queue item to the task handler, while remaining
|
||||||
|
* within server memory and time limit constraints.
|
||||||
|
*
|
||||||
|
* Tainacan comments: This is where we changed the mos from otiginal class.
|
||||||
|
* Each batch is a single array of data. There is no queue inside a batch.
|
||||||
|
*/
|
||||||
|
protected function handle() {
|
||||||
|
$this->lock_process();
|
||||||
|
//error_log('new request');
|
||||||
|
do {
|
||||||
|
$batch = $this->get_batch();
|
||||||
|
$task = $this->task( $batch->data );
|
||||||
|
|
||||||
|
// Update or close current batch.
|
||||||
|
if ( false !== $task ) {
|
||||||
|
$this->update( $batch->key, $task );
|
||||||
|
} else {
|
||||||
|
$this->close( $batch->key );
|
||||||
|
}
|
||||||
|
} while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() );
|
||||||
|
|
||||||
|
$this->unlock_process();
|
||||||
|
|
||||||
|
// Start next batch or complete process.
|
||||||
|
if ( ! $this->is_queue_empty() ) {
|
||||||
|
$this->dispatch();
|
||||||
|
} else {
|
||||||
|
$this->complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all batches.
|
||||||
|
*
|
||||||
|
* @return WC_Background_Process
|
||||||
|
*/
|
||||||
|
public function delete_all_batches() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$table = $this->table;
|
||||||
|
|
||||||
|
$wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE done = FALSE AND action LIKE %s", $this->action ) ); // @codingStandardsIgnoreLine.
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kill process.
|
||||||
|
*
|
||||||
|
* Stop processing queue items, clear cronjob and delete all batches.
|
||||||
|
*/
|
||||||
|
public function kill_process() {
|
||||||
|
if ( ! $this->is_queue_empty() ) {
|
||||||
|
$this->delete_all_batches();
|
||||||
|
wp_clear_scheduled_hook( $this->cron_hook_identifier );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -268,6 +268,16 @@ class Capabilities {
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public static $dependencies = [
|
||||||
|
"tainacan-items" => [
|
||||||
|
'edit_posts' => 'upload_files',
|
||||||
|
"edit_private_posts" => 'upload_files',
|
||||||
|
"edit_published_posts" => 'upload_files',
|
||||||
|
"edit_others_posts" => 'upload_files'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
private static $instance = null;
|
private static $instance = null;
|
||||||
|
|
||||||
public static function get_instance()
|
public static function get_instance()
|
||||||
|
@ -349,6 +359,43 @@ class Capabilities {
|
||||||
return $translations;
|
return $translations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function check_dependencies($role, $post_type, $cap, $add = true) {
|
||||||
|
if(
|
||||||
|
array_key_exists($post_type, self::$dependencies) &&
|
||||||
|
array_key_exists($cap, self::$dependencies[$post_type])
|
||||||
|
) {
|
||||||
|
$added = false;
|
||||||
|
if(! $role->has_cap(self::$dependencies[$post_type][$cap]) && $add) {
|
||||||
|
$role->add_cap(self::$dependencies[$post_type][$cap]);
|
||||||
|
$added = true;
|
||||||
|
}
|
||||||
|
if($role instanceof \WP_User && $add) { //moderator
|
||||||
|
$append_caps = get_user_meta($role->ID, '.tainacan-dependecies-caps', true);
|
||||||
|
if(! is_array($append_caps)) $append_caps = [];
|
||||||
|
if(
|
||||||
|
(! array_key_exists(self::$dependencies[$post_type][$cap], $append_caps) && $added ) || // we never added and need to add
|
||||||
|
(
|
||||||
|
array_key_exists(self::$dependencies[$post_type][$cap], $append_caps) &&
|
||||||
|
$append_caps[self::$dependencies[$post_type][$cap]] === false &&
|
||||||
|
$added
|
||||||
|
) // we added but before is not need to add
|
||||||
|
) {
|
||||||
|
$append_caps[self::$dependencies[$post_type][$cap]] = 0;
|
||||||
|
}
|
||||||
|
else { // we to not added this cap
|
||||||
|
$append_caps[self::$dependencies[$post_type][$cap]] = false;
|
||||||
|
}
|
||||||
|
if($append_caps[self::$dependencies[$post_type][$cap]] !== false) {
|
||||||
|
$append_caps[self::$dependencies[$post_type][$cap]]++; // add 1 to each collection he is a moderator
|
||||||
|
update_user_meta($role->ID, '.tainacan-dependecies-caps', $append_caps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self::$dependencies[$post_type][$cap];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update post_type caps using WordPress basic roles and register tainacan roles
|
* Update post_type caps using WordPress basic roles and register tainacan roles
|
||||||
*/
|
*/
|
||||||
|
@ -368,6 +415,7 @@ class Capabilities {
|
||||||
|
|
||||||
foreach ($caps as $cap) {
|
foreach ($caps as $cap) {
|
||||||
$role->add_cap($entity_cap->$cap);
|
$role->add_cap($entity_cap->$cap);
|
||||||
|
$this->check_dependencies($role, $post_type, $cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tainacan_roles = $this->get_tainacan_roles();
|
$tainacan_roles = $this->get_tainacan_roles();
|
||||||
|
@ -384,6 +432,7 @@ class Capabilities {
|
||||||
|
|
||||||
foreach ($caps as $cap) {
|
foreach ($caps as $cap) {
|
||||||
$tainacan_role->add_cap($entity_cap->$cap);
|
$tainacan_role->add_cap($entity_cap->$cap);
|
||||||
|
$this->check_dependencies($tainacan_role, $post_type, $cap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,6 +463,7 @@ class Capabilities {
|
||||||
|
|
||||||
foreach ($caps as $cap) {
|
foreach ($caps as $cap) {
|
||||||
$role->add_cap($collection_items_caps->$cap);
|
$role->add_cap($collection_items_caps->$cap);
|
||||||
|
$this->check_dependencies($role, 'tainacan-items', $cap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,6 +514,17 @@ class Capabilities {
|
||||||
$caps = $defaults_caps['tainacan-items']['editor'];
|
$caps = $defaults_caps['tainacan-items']['editor'];
|
||||||
foreach ($caps as $cap) {
|
foreach ($caps as $cap) {
|
||||||
$user->remove_cap($collection_items_caps->$cap);
|
$user->remove_cap($collection_items_caps->$cap);
|
||||||
|
$dep_cap = $this->check_dependencies($user, 'tainacan-items', $cap, false);
|
||||||
|
if($dep_cap !== false) {
|
||||||
|
$appended_caps = get_user_meta($user->ID, '.tainacan-dependecies-caps', true);
|
||||||
|
if(array_key_exists($dep_cap, $appended_caps) && $appended_caps[$dep_cap] !== false && $appended_caps[$dep_cap] > 0) {
|
||||||
|
$appended_caps[$dep_cap]--;
|
||||||
|
update_user_meta($user->ID, '.tainacan-dependecies-caps', $appended_caps);
|
||||||
|
if($appended_caps == 0) { // they are not a moderator of a collection, remove cap at all
|
||||||
|
$user->remove_cap($cap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,6 +548,7 @@ class Capabilities {
|
||||||
$caps = $defaults_caps['tainacan-items']['editor'];
|
$caps = $defaults_caps['tainacan-items']['editor'];
|
||||||
foreach ($caps as $cap) {
|
foreach ($caps as $cap) {
|
||||||
$user->add_cap($collection_items_caps->$cap);
|
$user->add_cap($collection_items_caps->$cap);
|
||||||
|
$this->check_dependencies($user, 'tainacan-items', $cap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -699,8 +699,14 @@ class Collection extends Entity {
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function set_moderators_ids( array $value ) {
|
function set_moderators_ids( $value ) {
|
||||||
|
if(!is_array($value)) {
|
||||||
|
if(empty($value)) {
|
||||||
|
$value = [];
|
||||||
|
} else {
|
||||||
|
throw new \Exception('moderators_ids must be a array of users ids');
|
||||||
|
}
|
||||||
|
}
|
||||||
// make sure you never have duplicated moderators
|
// make sure you never have duplicated moderators
|
||||||
$value = array_unique($value);
|
$value = array_unique($value);
|
||||||
|
|
||||||
|
|
|
@ -377,7 +377,7 @@ class Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if user can read this entity
|
* Return if user can edit this entity
|
||||||
* @param int|\WP_User|null $user the user for capability check, null for the current user
|
* @param int|\WP_User|null $user the user for capability check, null for the current user
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
@ -387,7 +387,7 @@ class Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if user can read this entity
|
* Return if user can delete this entity
|
||||||
* @param int|\WP_User|null $user the user for capability check, null for the current user
|
* @param int|\WP_User|null $user the user for capability check, null for the current user
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
@ -397,7 +397,7 @@ class Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if user can read this entity
|
* Return if user can publish this entity
|
||||||
* @param int|\WP_User|null $user the user for capability check, null for the current user
|
* @param int|\WP_User|null $user the user for capability check, null for the current user
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -30,7 +30,7 @@ class Item_Metadata_Entity extends Entity {
|
||||||
* @param Field $field Field Entity
|
* @param Field $field Field Entity
|
||||||
* @param int $meta_id ID for a specific meta row
|
* @param int $meta_id ID for a specific meta row
|
||||||
*/
|
*/
|
||||||
function __construct(Item $item, Field $field, $meta_id = null, $parent_meta_id = null) {
|
function __construct(Item $item = null, Field $field = null, $meta_id = null, $parent_meta_id = null) {
|
||||||
|
|
||||||
$this->set_item($item);
|
$this->set_item($item);
|
||||||
$this->set_field($field);
|
$this->set_field($field);
|
||||||
|
|
|
@ -273,23 +273,27 @@ class Log extends Entity {
|
||||||
* @param string $desc
|
* @param string $desc
|
||||||
* @param mixed $new_value
|
* @param mixed $new_value
|
||||||
* @param array $diffs
|
* @param array $diffs
|
||||||
* @param string $status 'publish', 'private' or 'pending'
|
* @param string $status 'publish', 'private', 'pending', 'processing' or 'error'
|
||||||
|
* @param int $parent
|
||||||
*
|
*
|
||||||
* @return \Tainacan\Entities\Log
|
* @return \Tainacan\Entities\Log
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function create( $msn = false, $desc = '', $new_value = null, $diffs = [], $status = 'publish' ) {
|
public static function create( $msn = false, $desc = '', $new_value = null, $diffs = [], $status = 'publish', $parent = 0 ) {
|
||||||
|
|
||||||
$log = new Log();
|
$log = new Log();
|
||||||
$log->set_title( $msn );
|
$log->set_title( $msn );
|
||||||
$log->set_description( $desc );
|
$log->set_description( $desc );
|
||||||
$log->set_status( $status );
|
$log->set_status( $status );
|
||||||
$log->set_log_diffs( $diffs );
|
$log->set_log_diffs( $diffs );
|
||||||
|
if($parent > 0) $log->set_parent($parent);
|
||||||
|
|
||||||
if(array_search( 'Tainacan\Traits\Entity_Collection_Relation', class_uses($new_value))) {
|
if(is_object($new_value) || is_string($new_value)) {
|
||||||
$log->set_collection_id( $new_value->get_collection_id() );
|
if(array_search( 'Tainacan\Traits\Entity_Collection_Relation', class_uses($new_value))) {
|
||||||
} elseif($new_value instanceof Collection){
|
$log->set_collection_id( $new_value->get_collection_id() );
|
||||||
$log->set_collection_id( $new_value->get_id());
|
} elseif($new_value instanceof Collection){
|
||||||
|
$log->set_collection_id( $new_value->get_id());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! is_null( $new_value ) ) {
|
if ( ! is_null( $new_value ) ) {
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
} else {
|
} else {
|
||||||
const instance = this;
|
const instance = this;
|
||||||
|
|
||||||
axios.post(`/taxonomy/${this.taxonomy_id}/terms`, {
|
axios.post(`/taxonomy/${this.taxonomy_id}/terms?hideempty=0&order=asc`, {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
parent: this.parent
|
parent: this.parent
|
||||||
})
|
})
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTermsFromTaxonomy(){
|
getTermsFromTaxonomy(){
|
||||||
axios.get('/taxonomy/' + this.taxonomy + '/terms?hideempty=0' ).then( res => {
|
axios.get('/taxonomy/' + this.taxonomy + '/terms?hideempty=0&order=asc' ).then( res => {
|
||||||
for (let item of res.data) {
|
for (let item of res.data) {
|
||||||
this.terms.push( item );
|
this.terms.push( item );
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getValuesCategory( taxonomy ){
|
getValuesCategory( taxonomy ){
|
||||||
return axios.get('/taxonomy/' + taxonomy + '/terms?hideempty=0' ).then( res => {
|
return axios.get('/taxonomy/' + taxonomy + '/terms?hideempty=0&order=asc' ).then( res => {
|
||||||
for (let item of res.data) {
|
for (let item of res.data) {
|
||||||
this.taxonomy = item.taxonomy;
|
this.taxonomy = item.taxonomy;
|
||||||
this.options.push(item);
|
this.options.push(item);
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
let promise = null;
|
let promise = null;
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
axios.get('/collection/'+ this.collection +'/fields/' + this.field + '?context=edit')
|
axios.get('/collection/'+ this.collection +'/fields/' + this.field)
|
||||||
.then( res => {
|
.then( res => {
|
||||||
let field = res.data;
|
let field = res.data;
|
||||||
promise = this.getValuesCategory( field.field_type_options.taxonomy_id );
|
promise = this.getValuesCategory( field.field_type_options.taxonomy_id );
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
let promise = null;
|
let promise = null;
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
axios.get('/collection/'+ this.collection +'/fields/' + this.field + '?context=edit')
|
axios.get('/collection/'+ this.collection +'/fields/' + this.field)
|
||||||
.then( res => {
|
.then( res => {
|
||||||
let field = res.data;
|
let field = res.data;
|
||||||
promise = this.getValuesCategory( field.field_type_options.taxonomy_id );
|
promise = this.getValuesCategory( field.field_type_options.taxonomy_id );
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
this.field = ( this.field_id ) ? this.field_id : this.filter.field.field_id ;
|
this.field = ( this.field_id ) ? this.field_id : this.filter.field.field_id ;
|
||||||
this.type = ( this.filter_type ) ? this.filter_type : this.filter.field.field_type;
|
this.type = ( this.filter_type ) ? this.filter_type : this.filter.field.field_type;
|
||||||
|
|
||||||
let in_route = '/collection/' + this.isRepositoryLevel + '/fields/' + this.field +'?context=edit';
|
let in_route = '/collection/' + this.collection + '/fields/' + this.field;
|
||||||
|
|
||||||
if(this.isRepositoryLevel){
|
if(this.isRepositoryLevel){
|
||||||
in_route = '/fields?context=edit';
|
in_route = '/fields/' + this.field;
|
||||||
}
|
}
|
||||||
|
|
||||||
axios.get(in_route)
|
axios.get(in_route)
|
||||||
|
@ -83,8 +83,9 @@
|
||||||
let promise = null;
|
let promise = null;
|
||||||
this.options = [];
|
this.options = [];
|
||||||
const q = query;
|
const q = query;
|
||||||
|
const endpoint = this.isRepositoryLevel ? '/fields/' + this.field : '/collection/'+ this.collection +'/fields/' + this.field;
|
||||||
axios.get('/collection/'+ this.collection +'/fields/' + this.field + '?context=edit')
|
|
||||||
|
axios.get(endpoint)
|
||||||
.then( res => {
|
.then( res => {
|
||||||
let field = res.data;
|
let field = res.data;
|
||||||
promise = this.getValuesCategory( field.field_type_options.taxonomy_id, q );
|
promise = this.getValuesCategory( field.field_type_options.taxonomy_id, q );
|
||||||
|
@ -102,7 +103,7 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getValuesCategory( taxonomy, query ){
|
getValuesCategory( taxonomy, query ){
|
||||||
return axios.get('/taxonomy/' + taxonomy + '/terms?hideempty=0' ).then( res => {
|
return axios.get('/taxonomy/' + taxonomy + '/terms?hideempty=0&order=asc' ).then( res => {
|
||||||
for (let term of res.data) {
|
for (let term of res.data) {
|
||||||
if( term.name.toLowerCase().indexOf( query.toLowerCase() ) >= 0 ){
|
if( term.name.toLowerCase().indexOf( query.toLowerCase() ) >= 0 ){
|
||||||
this.taxonomy = term.taxonomy;
|
this.taxonomy = term.taxonomy;
|
||||||
|
@ -129,7 +130,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTerm( taxonomy, id ){
|
getTerm( taxonomy, id ){
|
||||||
return axios.get('/taxonomy/' + taxonomy + '/terms/' + id ).then( res => {
|
return axios.get('/taxonomy/' + taxonomy + '/terms/' + id + '?order=asc&hideempty=0' ).then( res => {
|
||||||
this.$console.log(res);
|
this.$console.log(res);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div v-if="type === 'date'">
|
<div v-if="type === 'date'">
|
||||||
<b-datepicker
|
<b-datepicker
|
||||||
:placeholder="$i18n.get('label_selectbox_init')"
|
:placeholder="$i18n.get('label_selectbox_init')"
|
||||||
:class="{'has-content': date_init !== undefined && date_init !== ''}"
|
:class="{'has-content': date_init != undefined && date_init != ''}"
|
||||||
v-model="date_init"
|
v-model="date_init"
|
||||||
size="is-small"
|
size="is-small"
|
||||||
@focus="isTouched = true"
|
@focus="isTouched = true"
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
icon="calendar-today"/>
|
icon="calendar-today"/>
|
||||||
<b-datepicker
|
<b-datepicker
|
||||||
:placeholder="$i18n.get('label_selectbox_init')"
|
:placeholder="$i18n.get('label_selectbox_init')"
|
||||||
:class="{'has-content': date_end !== undefined && date_end !== ''}"
|
:class="{'has-content': date_end != undefined && date_end != ''}"
|
||||||
v-model="date_end"
|
v-model="date_end"
|
||||||
size="is-small"
|
size="is-small"
|
||||||
@input="validate_values()"
|
@input="validate_values()"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
class="columns"
|
class="columns"
|
||||||
v-else>
|
v-else>
|
||||||
<b-input
|
<b-input
|
||||||
:class="{'has-content': value_init !== undefined && value_init !== ''}"
|
:class="{'has-content': value_init != undefined && value_init != ''}"
|
||||||
size="is-small"
|
size="is-small"
|
||||||
type="number"
|
type="number"
|
||||||
step="any"
|
step="any"
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
class="column"
|
class="column"
|
||||||
v-model="value_init"/>
|
v-model="value_init"/>
|
||||||
<b-input
|
<b-input
|
||||||
:class="{'has-content': value_end !== undefined && value_end !== ''}"
|
:class="{'has-content': value_end != undefined && value_end != ''}"
|
||||||
size="is-small"
|
size="is-small"
|
||||||
type="number"
|
type="number"
|
||||||
step="any"
|
step="any"
|
||||||
|
|
|
@ -174,7 +174,6 @@
|
||||||
padding-top: 0px !important;
|
padding-top: 0px !important;
|
||||||
select {
|
select {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border: none;
|
|
||||||
border-radius: 1px !important;
|
border-radius: 1px !important;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
height: 30px !important;
|
height: 30px !important;
|
||||||
|
@ -207,7 +206,6 @@
|
||||||
.input, .textarea, .taginput-container {
|
.input, .textarea, .taginput-container {
|
||||||
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border: none !important;
|
|
||||||
border-radius: 1px !important;
|
border-radius: 1px !important;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: $tainacan-input-color;
|
color: $tainacan-input-color;
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* WP Async Request
|
||||||
|
*
|
||||||
|
* @package WP-Background-Processing
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! class_exists( 'WP_Async_Request' ) ) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract WP_Async_Request class.
|
||||||
|
*
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
abstract class WP_Async_Request {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix
|
||||||
|
*
|
||||||
|
* (default value: 'wp')
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $prefix = 'wp';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action
|
||||||
|
*
|
||||||
|
* (default value: 'async_request')
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $action = 'async_request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifier
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data
|
||||||
|
*
|
||||||
|
* (default value: array())
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $data = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate new async request
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
$this->identifier = $this->prefix . '_' . $this->action;
|
||||||
|
|
||||||
|
add_action( 'wp_ajax_' . $this->identifier, array( $this, 'maybe_handle' ) );
|
||||||
|
add_action( 'wp_ajax_nopriv_' . $this->identifier, array( $this, 'maybe_handle' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set data used during the request
|
||||||
|
*
|
||||||
|
* @param array $data Data.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function data( $data ) {
|
||||||
|
$this->data = $data;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch the async request
|
||||||
|
*
|
||||||
|
* @return array|WP_Error
|
||||||
|
*/
|
||||||
|
public function dispatch() {
|
||||||
|
$url = add_query_arg( $this->get_query_args(), $this->get_query_url() );
|
||||||
|
$args = $this->get_post_args();
|
||||||
|
|
||||||
|
return wp_remote_post( esc_url_raw( $url ), $args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get query args
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function get_query_args() {
|
||||||
|
if ( property_exists( $this, 'query_args' ) ) {
|
||||||
|
return $this->query_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'action' => $this->identifier,
|
||||||
|
'nonce' => wp_create_nonce( $this->identifier ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get query URL
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function get_query_url() {
|
||||||
|
if ( property_exists( $this, 'query_url' ) ) {
|
||||||
|
return $this->query_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return admin_url( 'admin-ajax.php' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get post args
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function get_post_args() {
|
||||||
|
if ( property_exists( $this, 'post_args' ) ) {
|
||||||
|
return $this->post_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'timeout' => 0.01,
|
||||||
|
'blocking' => false,
|
||||||
|
'body' => $this->data,
|
||||||
|
'cookies' => $_COOKIE,
|
||||||
|
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maybe handle
|
||||||
|
*
|
||||||
|
* Check for correct nonce and pass to handler.
|
||||||
|
*/
|
||||||
|
public function maybe_handle() {
|
||||||
|
// Don't lock up other requests while processing
|
||||||
|
session_write_close();
|
||||||
|
|
||||||
|
check_ajax_referer( $this->identifier, 'nonce' );
|
||||||
|
|
||||||
|
$this->handle();
|
||||||
|
|
||||||
|
wp_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle
|
||||||
|
*
|
||||||
|
* Override this method to perform any actions required
|
||||||
|
* during the async request.
|
||||||
|
*/
|
||||||
|
abstract protected function handle();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,506 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* WP Background Process
|
||||||
|
*
|
||||||
|
* @package WP-Background-Processing
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! class_exists( 'WP_Background_Process' ) ) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract WP_Background_Process class.
|
||||||
|
*
|
||||||
|
* @abstract
|
||||||
|
* @extends WP_Async_Request
|
||||||
|
*/
|
||||||
|
abstract class WP_Background_Process extends WP_Async_Request {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action
|
||||||
|
*
|
||||||
|
* (default value: 'background_process')
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $action = 'background_process';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start time of current process.
|
||||||
|
*
|
||||||
|
* (default value: 0)
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $start_time = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cron_hook_identifier
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $cron_hook_identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cron_interval_identifier
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected $cron_interval_identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate new background process
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->cron_hook_identifier = $this->identifier . '_cron';
|
||||||
|
$this->cron_interval_identifier = $this->identifier . '_cron_interval';
|
||||||
|
|
||||||
|
add_action( $this->cron_hook_identifier, array( $this, 'handle_cron_healthcheck' ) );
|
||||||
|
add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function dispatch() {
|
||||||
|
// Schedule the cron healthcheck.
|
||||||
|
$this->schedule_event();
|
||||||
|
|
||||||
|
// Perform remote post.
|
||||||
|
return parent::dispatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push to queue
|
||||||
|
*
|
||||||
|
* @param mixed $data Data.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function push_to_queue( $data ) {
|
||||||
|
$this->data[] = $data;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save queue
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function save() {
|
||||||
|
$key = $this->generate_key();
|
||||||
|
|
||||||
|
if ( ! empty( $this->data ) ) {
|
||||||
|
update_site_option( $key, $this->data );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update queue
|
||||||
|
*
|
||||||
|
* @param string $key Key.
|
||||||
|
* @param array $data Data.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function update( $key, $data ) {
|
||||||
|
if ( ! empty( $data ) ) {
|
||||||
|
update_site_option( $key, $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete queue
|
||||||
|
*
|
||||||
|
* @param string $key Key.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function delete( $key ) {
|
||||||
|
delete_site_option( $key );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate key
|
||||||
|
*
|
||||||
|
* Generates a unique key based on microtime. Queue items are
|
||||||
|
* given a unique key so that they can be merged upon save.
|
||||||
|
*
|
||||||
|
* @param int $length Length.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function generate_key( $length = 64 ) {
|
||||||
|
$unique = md5( microtime() . rand() );
|
||||||
|
$prepend = $this->identifier . '_batch_';
|
||||||
|
|
||||||
|
return substr( $prepend . $unique, 0, $length );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maybe process queue
|
||||||
|
*
|
||||||
|
* Checks whether data exists within the queue and that
|
||||||
|
* the process is not already running.
|
||||||
|
*/
|
||||||
|
public function maybe_handle() {
|
||||||
|
// Don't lock up other requests while processing
|
||||||
|
session_write_close();
|
||||||
|
|
||||||
|
if ( $this->is_process_running() ) {
|
||||||
|
// Background process already running.
|
||||||
|
wp_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->is_queue_empty() ) {
|
||||||
|
// No data to process.
|
||||||
|
wp_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
check_ajax_referer( $this->identifier, 'nonce' );
|
||||||
|
|
||||||
|
$this->handle();
|
||||||
|
|
||||||
|
wp_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is queue empty
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function is_queue_empty() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$table = $wpdb->options;
|
||||||
|
$column = 'option_name';
|
||||||
|
|
||||||
|
if ( is_multisite() ) {
|
||||||
|
$table = $wpdb->sitemeta;
|
||||||
|
$column = 'meta_key';
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
||||||
|
|
||||||
|
$count = $wpdb->get_var( $wpdb->prepare( "
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM {$table}
|
||||||
|
WHERE {$column} LIKE %s
|
||||||
|
", $key ) );
|
||||||
|
|
||||||
|
return ( $count > 0 ) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is process running
|
||||||
|
*
|
||||||
|
* Check whether the current process is already running
|
||||||
|
* in a background process.
|
||||||
|
*/
|
||||||
|
protected function is_process_running() {
|
||||||
|
if ( get_site_transient( $this->identifier . '_process_lock' ) ) {
|
||||||
|
// Process already running.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock process
|
||||||
|
*
|
||||||
|
* Lock the process so that multiple instances can't run simultaneously.
|
||||||
|
* Override if applicable, but the duration should be greater than that
|
||||||
|
* defined in the time_exceeded() method.
|
||||||
|
*/
|
||||||
|
protected function lock_process() {
|
||||||
|
$this->start_time = time(); // Set start time of current process.
|
||||||
|
|
||||||
|
$lock_duration = ( property_exists( $this, 'queue_lock_time' ) ) ? $this->queue_lock_time : 60; // 1 minute
|
||||||
|
$lock_duration = apply_filters( $this->identifier . '_queue_lock_time', $lock_duration );
|
||||||
|
|
||||||
|
set_site_transient( $this->identifier . '_process_lock', microtime(), $lock_duration );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock process
|
||||||
|
*
|
||||||
|
* Unlock the process so that other instances can spawn.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
protected function unlock_process() {
|
||||||
|
delete_site_transient( $this->identifier . '_process_lock' );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get batch
|
||||||
|
*
|
||||||
|
* @return stdClass Return the first batch from the queue
|
||||||
|
*/
|
||||||
|
protected function get_batch() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$table = $wpdb->options;
|
||||||
|
$column = 'option_name';
|
||||||
|
$key_column = 'option_id';
|
||||||
|
$value_column = 'option_value';
|
||||||
|
|
||||||
|
if ( is_multisite() ) {
|
||||||
|
$table = $wpdb->sitemeta;
|
||||||
|
$column = 'meta_key';
|
||||||
|
$key_column = 'meta_id';
|
||||||
|
$value_column = 'meta_value';
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
||||||
|
|
||||||
|
$query = $wpdb->get_row( $wpdb->prepare( "
|
||||||
|
SELECT *
|
||||||
|
FROM {$table}
|
||||||
|
WHERE {$column} LIKE %s
|
||||||
|
ORDER BY {$key_column} ASC
|
||||||
|
LIMIT 1
|
||||||
|
", $key ) );
|
||||||
|
|
||||||
|
$batch = new stdClass();
|
||||||
|
$batch->key = $query->$column;
|
||||||
|
$batch->data = maybe_unserialize( $query->$value_column );
|
||||||
|
|
||||||
|
return $batch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle
|
||||||
|
*
|
||||||
|
* Pass each queue item to the task handler, while remaining
|
||||||
|
* within server memory and time limit constraints.
|
||||||
|
*/
|
||||||
|
protected function handle() {
|
||||||
|
$this->lock_process();
|
||||||
|
|
||||||
|
do {
|
||||||
|
$batch = $this->get_batch();
|
||||||
|
|
||||||
|
foreach ( $batch->data as $key => $value ) {
|
||||||
|
$task = $this->task( $value );
|
||||||
|
|
||||||
|
if ( false !== $task ) {
|
||||||
|
$batch->data[ $key ] = $task;
|
||||||
|
} else {
|
||||||
|
unset( $batch->data[ $key ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->time_exceeded() || $this->memory_exceeded() ) {
|
||||||
|
// Batch limits reached.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update or delete current batch.
|
||||||
|
if ( ! empty( $batch->data ) ) {
|
||||||
|
$this->update( $batch->key, $batch->data );
|
||||||
|
} else {
|
||||||
|
$this->delete( $batch->key );
|
||||||
|
}
|
||||||
|
} while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() );
|
||||||
|
|
||||||
|
$this->unlock_process();
|
||||||
|
|
||||||
|
// Start next batch or complete process.
|
||||||
|
if ( ! $this->is_queue_empty() ) {
|
||||||
|
$this->dispatch();
|
||||||
|
} else {
|
||||||
|
$this->complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory exceeded
|
||||||
|
*
|
||||||
|
* Ensures the batch process never exceeds 90%
|
||||||
|
* of the maximum WordPress memory.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function memory_exceeded() {
|
||||||
|
$memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory
|
||||||
|
$current_memory = memory_get_usage( true );
|
||||||
|
$return = false;
|
||||||
|
|
||||||
|
if ( $current_memory >= $memory_limit ) {
|
||||||
|
$return = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apply_filters( $this->identifier . '_memory_exceeded', $return );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get memory limit
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function get_memory_limit() {
|
||||||
|
if ( function_exists( 'ini_get' ) ) {
|
||||||
|
$memory_limit = ini_get( 'memory_limit' );
|
||||||
|
} else {
|
||||||
|
// Sensible default.
|
||||||
|
$memory_limit = '128M';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $memory_limit || -1 === intval( $memory_limit ) ) {
|
||||||
|
// Unlimited, set to 32GB.
|
||||||
|
$memory_limit = '32000M';
|
||||||
|
}
|
||||||
|
|
||||||
|
return intval( $memory_limit ) * 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time exceeded.
|
||||||
|
*
|
||||||
|
* Ensures the batch never exceeds a sensible time limit.
|
||||||
|
* A timeout limit of 30s is common on shared hosting.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function time_exceeded() {
|
||||||
|
$finish = $this->start_time + apply_filters( $this->identifier . '_default_time_limit', 20 ); // 20 seconds
|
||||||
|
$return = false;
|
||||||
|
|
||||||
|
if ( time() >= $finish ) {
|
||||||
|
$return = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apply_filters( $this->identifier . '_time_exceeded', $return );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete.
|
||||||
|
*
|
||||||
|
* Override if applicable, but ensure that the below actions are
|
||||||
|
* performed, or, call parent::complete().
|
||||||
|
*/
|
||||||
|
protected function complete() {
|
||||||
|
// Unschedule the cron healthcheck.
|
||||||
|
$this->clear_scheduled_event();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule cron healthcheck
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $schedules Schedules.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function schedule_cron_healthcheck( $schedules ) {
|
||||||
|
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
|
||||||
|
|
||||||
|
if ( property_exists( $this, 'cron_interval' ) ) {
|
||||||
|
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds every 5 minutes to the existing schedules.
|
||||||
|
$schedules[ $this->identifier . '_cron_interval' ] = array(
|
||||||
|
'interval' => MINUTE_IN_SECONDS * $interval,
|
||||||
|
'display' => sprintf( __( 'Every %d Minutes' ), $interval ),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $schedules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle cron healthcheck
|
||||||
|
*
|
||||||
|
* Restart the background process if not already running
|
||||||
|
* and data exists in the queue.
|
||||||
|
*/
|
||||||
|
public function handle_cron_healthcheck() {
|
||||||
|
if ( $this->is_process_running() ) {
|
||||||
|
// Background process already running.
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->is_queue_empty() ) {
|
||||||
|
// No data to process.
|
||||||
|
$this->clear_scheduled_event();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->handle();
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule event
|
||||||
|
*/
|
||||||
|
protected function schedule_event() {
|
||||||
|
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
|
||||||
|
wp_schedule_event( time(), $this->cron_interval_identifier, $this->cron_hook_identifier );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear scheduled event
|
||||||
|
*/
|
||||||
|
protected function clear_scheduled_event() {
|
||||||
|
$timestamp = wp_next_scheduled( $this->cron_hook_identifier );
|
||||||
|
|
||||||
|
if ( $timestamp ) {
|
||||||
|
wp_unschedule_event( $timestamp, $this->cron_hook_identifier );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel Process
|
||||||
|
*
|
||||||
|
* Stop processing queue items, clear cronjob and delete batch.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function cancel_process() {
|
||||||
|
if ( ! $this->is_queue_empty() ) {
|
||||||
|
$batch = $this->get_batch();
|
||||||
|
|
||||||
|
$this->delete( $batch->key );
|
||||||
|
|
||||||
|
wp_clear_scheduled_hook( $this->cron_hook_identifier );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task
|
||||||
|
*
|
||||||
|
* Override this method to perform any actions required on each
|
||||||
|
* queue item. Return the modified item for further processing
|
||||||
|
* in the next pass through. Or, return false to remove the
|
||||||
|
* item from the queue.
|
||||||
|
*
|
||||||
|
* @param mixed $item Queue item to iterate over.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
abstract protected function task( $item );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -211,7 +211,7 @@ class Logs extends Repository {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update( $object, $new_values = null ) {
|
public function update( $object, $new_values = null ) {
|
||||||
|
return $this->insert($object);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetch_last() {
|
public function fetch_last() {
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Tainacan\Repositories;
|
||||||
use Tainacan\Entities;
|
use Tainacan\Entities;
|
||||||
use Tainacan\Entities\Entity;
|
use Tainacan\Entities\Entity;
|
||||||
use Tainacan;
|
use Tainacan;
|
||||||
|
use Tainacan\Repositories;
|
||||||
use \Respect\Validation\Validator as v;
|
use \Respect\Validation\Validator as v;
|
||||||
|
|
||||||
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
|
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
|
||||||
|
@ -427,6 +428,9 @@ abstract class Repository {
|
||||||
*/
|
*/
|
||||||
public static function get_entity_by_post_type( $post_type, $post = 0 ) {
|
public static function get_entity_by_post_type( $post_type, $post = 0 ) {
|
||||||
$prefix = substr( $post_type, 0, strlen( Entities\Collection::$db_identifier_prefix ) );
|
$prefix = substr( $post_type, 0, strlen( Entities\Collection::$db_identifier_prefix ) );
|
||||||
|
$item_metadata = Repositories\Item_Metadata::get_instance();
|
||||||
|
$item_metadata_entity = new $item_metadata->entities_type(null, null);
|
||||||
|
$item_metadata_post_type = $item_metadata_entity::get_post_type();
|
||||||
|
|
||||||
// Is it a collection Item?
|
// Is it a collection Item?
|
||||||
if ( $prefix == Entities\Collection::$db_identifier_prefix ) {
|
if ( $prefix == Entities\Collection::$db_identifier_prefix ) {
|
||||||
|
@ -436,15 +440,15 @@ abstract class Repository {
|
||||||
} else {
|
} else {
|
||||||
throw new \Exception( 'Collection object not found for this post' );
|
throw new \Exception( 'Collection object not found for this post' );
|
||||||
}
|
}
|
||||||
} elseif ( $post_type === \Tainacan\Repositories\Item_Metadata::get_instance()->entities_type::get_post_type() ) {
|
} elseif ( $post_type === $item_metadata_post_type ) {
|
||||||
return new Entities\Item_Metadata_Entity( null, null );
|
return new Entities\Item_Metadata_Entity( null, null );
|
||||||
} else {
|
} else {
|
||||||
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
|
$Tainacan_Collections = Repositories\Collections::get_instance();
|
||||||
$Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
|
$Tainacan_Filters = Repositories\Filters::get_instance();
|
||||||
$Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance();
|
$Tainacan_Logs = Repositories\Logs::get_instance();
|
||||||
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
$Tainacan_Fields = Repositories\Fields::get_instance();
|
||||||
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance();
|
$Tainacan_Taxonomies = Repositories\Taxonomies::get_instance();
|
||||||
$Tainacan_Terms = \Tainacan\Repositories\Terms::get_instance();
|
$Tainacan_Terms = Repositories\Terms::get_instance();
|
||||||
|
|
||||||
$tnc_globals = [
|
$tnc_globals = [
|
||||||
$Tainacan_Collections,
|
$Tainacan_Collections,
|
||||||
|
@ -455,7 +459,9 @@ abstract class Repository {
|
||||||
$Tainacan_Logs
|
$Tainacan_Logs
|
||||||
];
|
];
|
||||||
foreach ( $tnc_globals as $tnc_repository ) {
|
foreach ( $tnc_globals as $tnc_repository ) {
|
||||||
$entity_post_type = $tnc_repository->entities_type::get_post_type();
|
$tnc_entity = new $tnc_repository->entities_type();
|
||||||
|
$entity_post_type = $tnc_entity::get_post_type();
|
||||||
|
|
||||||
if ( $entity_post_type == $post_type ) {
|
if ( $entity_post_type == $post_type ) {
|
||||||
return new $tnc_repository->entities_type( $post );
|
return new $tnc_repository->entities_type( $post );
|
||||||
}
|
}
|
||||||
|
@ -500,7 +506,9 @@ abstract class Repository {
|
||||||
$Tainacan_Logs
|
$Tainacan_Logs
|
||||||
];
|
];
|
||||||
foreach ( $tnc_globals as $tnc_repository ) {
|
foreach ( $tnc_globals as $tnc_repository ) {
|
||||||
$entity_post_type = $tnc_repository->entities_type::get_post_type();
|
$tnc_entity = new $tnc_repository->entities_type();
|
||||||
|
$entity_post_type = $tnc_entity::get_post_type();
|
||||||
|
|
||||||
if ( $entity_post_type == $post_type ) {
|
if ( $entity_post_type == $post_type ) {
|
||||||
return $tnc_repository;
|
return $tnc_repository;
|
||||||
}
|
}
|
||||||
|
@ -683,7 +691,7 @@ abstract class Repository {
|
||||||
public function diff( $old = 0, $new ) {
|
public function diff( $old = 0, $new ) {
|
||||||
$old_entity = null;
|
$old_entity = null;
|
||||||
|
|
||||||
if ( $old === 0 ) { // self diff or other entity?
|
if ( $old === 0 || is_array($old) && count($old) == 0 ) { // self diff or other entity?
|
||||||
$id = $new->get_id();
|
$id = $new->get_id();
|
||||||
|
|
||||||
if ( ! empty( $id ) ) { // there is a repository entity?
|
if ( ! empty( $id ) ) { // there is a repository entity?
|
||||||
|
|
|
@ -8,7 +8,6 @@ const TAINACAN_TRAITS_DIR = __DIR__ . '/traits/';
|
||||||
const TAINACAN_VENDOR_DIR = __DIR__ . '/../vendor/';
|
const TAINACAN_VENDOR_DIR = __DIR__ . '/../vendor/';
|
||||||
const TAINACAN_TAPI_DIR = __DIR__ . '/../api/';
|
const TAINACAN_TAPI_DIR = __DIR__ . '/../api/';
|
||||||
const TAINACAN_ENDPOINTS_DIR = __DIR__ . '/../api/endpoints/';
|
const TAINACAN_ENDPOINTS_DIR = __DIR__ . '/../api/endpoints/';
|
||||||
const TAINACAN_HELPERS_DIR = __DIR__ . '/../helpers/';
|
|
||||||
const TAINACAN_IMPORTER_DIR = __DIR__ . '/../importer/';
|
const TAINACAN_IMPORTER_DIR = __DIR__ . '/../importer/';
|
||||||
const TAINACAN_EXPOSERS_DIR = __DIR__ . '/../exposers/';
|
const TAINACAN_EXPOSERS_DIR = __DIR__ . '/../exposers/';
|
||||||
|
|
||||||
|
@ -25,11 +24,17 @@ const DIRS = [
|
||||||
TAINACAN_EXPOSERS_DIR
|
TAINACAN_EXPOSERS_DIR
|
||||||
];
|
];
|
||||||
|
|
||||||
|
require_once('libs/wp-async-request.php');
|
||||||
|
require_once('libs/wp-background-process.php');
|
||||||
|
require_once('class-tainacan-background-process.php');
|
||||||
|
require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-bg-importer.php');
|
||||||
|
|
||||||
require_once(TAINACAN_VENDOR_DIR . 'autoload.php');
|
require_once(TAINACAN_VENDOR_DIR . 'autoload.php');
|
||||||
require_once(TAINACAN_HELPERS_DIR . 'class-tainacan-helpers-html.php');
|
|
||||||
require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-importer.php');
|
require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-importer.php');
|
||||||
|
require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-importer-handler.php');
|
||||||
require_once(TAINACAN_EXPOSERS_DIR . 'class-tainacan-exposers.php');
|
require_once(TAINACAN_EXPOSERS_DIR . 'class-tainacan-exposers.php');
|
||||||
|
|
||||||
|
|
||||||
spl_autoload_register('tainacan_autoload');
|
spl_autoload_register('tainacan_autoload');
|
||||||
|
|
||||||
function tainacan_autoload($class_name){
|
function tainacan_autoload($class_name){
|
||||||
|
@ -130,4 +135,5 @@ require_once(__DIR__ . '/../theme-helper/class-tainacan-theme-helper.php');
|
||||||
require_once(__DIR__ . '/../theme-helper/template-tags.php');
|
require_once(__DIR__ . '/../theme-helper/template-tags.php');
|
||||||
$Tainacan_Theme_Helper = \Tainacan\Theme_Helper::get_instance();
|
$Tainacan_Theme_Helper = \Tainacan\Theme_Helper::get_instance();
|
||||||
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -22,11 +22,9 @@ class DevInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function __construct() {
|
private function __construct() {
|
||||||
|
|
||||||
add_action('add_meta_boxes', array(&$this, 'register_metaboxes'));
|
add_action('admin_init', [$this, 'admin_init']);
|
||||||
add_action('save_post', array(&$this, 'save_post'), 10, 2);
|
|
||||||
add_action('admin_enqueue_scripts', array(&$this, 'add_admin_js'));
|
|
||||||
|
|
||||||
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
|
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
|
||||||
$Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
|
$Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
|
||||||
$Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance();
|
$Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance();
|
||||||
|
@ -36,12 +34,21 @@ class DevInterface {
|
||||||
$repositories = [$Tainacan_Collections, $Tainacan_Filters, $Tainacan_Logs, $Tainacan_Fields, $Tainacan_Taxonomies];
|
$repositories = [$Tainacan_Collections, $Tainacan_Filters, $Tainacan_Logs, $Tainacan_Fields, $Tainacan_Taxonomies];
|
||||||
|
|
||||||
foreach ($repositories as $repo) {
|
foreach ($repositories as $repo) {
|
||||||
$cpt = $repo->entities_type::get_post_type();
|
$tnc_entity = new $repo->entities_type();
|
||||||
|
$cpt = $tnc_entity::get_post_type();
|
||||||
$this->repositories[$cpt] = $repo;
|
$this->repositories[$cpt] = $repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function admin_init() {
|
||||||
|
if ( function_exists('get_current_screen')) { // check if is in wordpress builtin admin screen
|
||||||
|
add_action('add_meta_boxes', array(&$this, 'register_metaboxes'));
|
||||||
|
add_action('save_post', array(&$this, 'save_post'), 10, 2);
|
||||||
|
add_action('admin_enqueue_scripts', array(&$this, 'add_admin_js'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function add_admin_js() {
|
function add_admin_js() {
|
||||||
global $TAINACAN_BASE_URL;
|
global $TAINACAN_BASE_URL;
|
||||||
$components = ( has_filter( 'tainacan_register_web_components' ) ) ? apply_filters('tainacan_register_web_components') : [];
|
$components = ( has_filter( 'tainacan_register_web_components' ) ) ? apply_filters('tainacan_register_web_components') : [];
|
||||||
|
@ -441,7 +448,7 @@ class DevInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$entity->set_mapped_property($prop, $value);
|
$entity->set($prop, $value);
|
||||||
|
|
||||||
|
|
||||||
if ($entity->validate_prop($prop)) {
|
if ($entity->validate_prop($prop)) {
|
||||||
|
@ -459,8 +466,8 @@ class DevInterface {
|
||||||
update_post_meta($post_id, 'filter_type_options', $_POST['filter_type_'.strtolower( $value ) ] );
|
update_post_meta($post_id, 'filter_type_options', $_POST['filter_type_'.strtolower( $value ) ] );
|
||||||
update_post_meta($post_id, 'filter_type', wp_slash( get_class( new $class() ) ) );
|
update_post_meta($post_id, 'filter_type', wp_slash( get_class( new $class() ) ) );
|
||||||
} elseif ($mapped['map'] == 'meta' || $mapped['map'] == 'meta_multi') {
|
} elseif ($mapped['map'] == 'meta' || $mapped['map'] == 'meta_multi') {
|
||||||
|
$diffs = [];
|
||||||
$repo->insert_metadata($entity, $prop);
|
$repo->insert_metadata($entity, $prop, $diffs);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -493,7 +500,8 @@ class DevInterface {
|
||||||
// for new Items
|
// for new Items
|
||||||
if (!$entity->get_collection_id()) {
|
if (!$entity->get_collection_id()) {
|
||||||
$entity->set_collection($cpts[$post_type]);
|
$entity->set_collection($cpts[$post_type]);
|
||||||
$Tainacan_Items->insert_metadata($entity, 'collection_id');
|
$diffs = [];
|
||||||
|
$Tainacan_Items->insert_metadata($entity, 'collection_id', $diffs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ class Exposers {
|
||||||
protected $types = [];
|
protected $types = [];
|
||||||
protected $mappers = [];
|
protected $mappers = [];
|
||||||
private static $instance = null;
|
private static $instance = null;
|
||||||
|
private static $request = null;
|
||||||
const MAPPER_CLASS_PREFIX = 'Tainacan\Exposers\Mappers\\';
|
const MAPPER_CLASS_PREFIX = 'Tainacan\Exposers\Mappers\\';
|
||||||
|
|
||||||
public static function get_instance() {
|
public static function get_instance() {
|
||||||
|
@ -35,8 +36,9 @@ class Exposers {
|
||||||
do_action('tainacan-register-exposer-mappers');
|
do_action('tainacan-register-exposer-mappers');
|
||||||
|
|
||||||
|
|
||||||
add_filter( 'rest_request_after_callbacks', [$this, 'rest_request_after_callbacks'], 10, 3 ); //exposer mapping
|
add_filter( 'rest_request_after_callbacks', [$this, 'rest_request_after_callbacks'], 10, 3 ); //exposer types
|
||||||
add_filter( 'tainacan-rest-response', [$this, 'rest_response'], 10, 2 ); // exposer types
|
add_filter( 'tainacan-rest-response', [$this, 'rest_response'], 10, 2 ); // exposer mapper
|
||||||
|
add_filter( 'tainacan-admin-i18n', [$this, 'mappers_i18n']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,12 +47,15 @@ class Exposers {
|
||||||
* @param $class_name string | object The class name or the instance
|
* @param $class_name string | object The class name or the instance
|
||||||
*/
|
*/
|
||||||
public function register_exposer_type( $class_name ){
|
public function register_exposer_type( $class_name ){
|
||||||
|
$obj = $class_name;
|
||||||
if( is_object( $class_name ) ){
|
if( is_object( $class_name ) ){
|
||||||
$class_name = get_class( $class_name );
|
$class_name = get_class( $class_name );
|
||||||
|
} else {
|
||||||
|
$obj = new $class_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!in_array( $class_name, $this->types)){
|
if(!in_array( $class_name, $this->types)){
|
||||||
$this->types[] = $class_name;
|
$this->types[$obj->slug] = $class_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +65,15 @@ class Exposers {
|
||||||
* @param $class_name string | object The class name or the object instance
|
* @param $class_name string | object The class name or the object instance
|
||||||
*/
|
*/
|
||||||
public function register_exposer_mapper( $class_name ){
|
public function register_exposer_mapper( $class_name ){
|
||||||
|
$obj = $class_name;
|
||||||
if( is_object( $class_name ) ){
|
if( is_object( $class_name ) ){
|
||||||
$class_name = get_class( $class_name );
|
$class_name = get_class( $class_name );
|
||||||
|
} else {
|
||||||
|
$obj = new $class_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!in_array( $class_name, $this->mappers)){
|
if(!in_array( $class_name, $this->mappers)){
|
||||||
$this->mappers[] = $class_name;
|
$this->mappers[$obj->slug] = $class_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +85,15 @@ class Exposers {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function check_class_name($class_name, $root = false, $prefix = 'Tainacan\Exposers\Types\\') {
|
public function check_class_name($class_name, $root = false, $prefix = 'Tainacan\Exposers\Types\\') {
|
||||||
|
if(is_string($class_name)) {
|
||||||
|
if(array_key_exists($class_name, $this->types)) {
|
||||||
|
$class_name = $this->types[$class_name];
|
||||||
|
$prefix = '';
|
||||||
|
} elseif( array_key_exists($class_name, $this->mappers)) {
|
||||||
|
$class_name = $this->mappers[$class_name];
|
||||||
|
$prefix = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
$class = $prefix.sanitize_text_field($class_name);
|
$class = $prefix.sanitize_text_field($class_name);
|
||||||
$class = str_replace(['-', ' '], ['_', '_'], $class);
|
$class = str_replace(['-', ' '], ['_', '_'], $class);
|
||||||
|
|
||||||
|
@ -90,7 +107,7 @@ class Exposers {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function rest_response($item_arr, $request) {
|
public function rest_response($item_arr, $request) {
|
||||||
if($request->get_method() == 'GET' && substr($request->get_route(), 0, strlen('/tainacan/v2')) == '/tainacan/v2') {
|
if($request->get_method() == 'GET' && $this->is_tainacan_request($request)) {
|
||||||
if($exposer = $this->request_has_mapper($request)) {
|
if($exposer = $this->request_has_mapper($request)) {
|
||||||
if(substr($request->get_route(), 0, strlen('/tainacan/v2/items')) == '/tainacan/v2/items') { //TODO do it at rest not here
|
if(substr($request->get_route(), 0, strlen('/tainacan/v2/items')) == '/tainacan/v2/items') { //TODO do it at rest not here
|
||||||
$repos_items = \Tainacan\Repositories\Items::get_instance();
|
$repos_items = \Tainacan\Repositories\Items::get_instance();
|
||||||
|
@ -152,6 +169,15 @@ class Exposers {
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if is a tainacan request
|
||||||
|
* @param \WP_REST_Request $request
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function is_tainacan_request($request) {
|
||||||
|
return substr($request->get_route(), 0, strlen('/tainacan/v2')) == '/tainacan/v2';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adapt request response to exposer type
|
* adapt request response to exposer type
|
||||||
* @param \WP_REST_Response $response
|
* @param \WP_REST_Response $response
|
||||||
|
@ -160,11 +186,17 @@ class Exposers {
|
||||||
* @return \WP_REST_Response
|
* @return \WP_REST_Response
|
||||||
*/
|
*/
|
||||||
public function rest_request_after_callbacks( $response, $handler, $request ) {
|
public function rest_request_after_callbacks( $response, $handler, $request ) {
|
||||||
if($request->get_method() == 'GET' && substr($request->get_route(), 0, strlen('/tainacan/v2')) == '/tainacan/v2') {
|
if($this->is_tainacan_request($request) && $response instanceof \WP_REST_Response ) {
|
||||||
if($exposer = $this->request_has_type($request)) {
|
if($request->get_method() == 'GET') {
|
||||||
return $exposer->rest_request_after_callbacks($response, $handler, $request);
|
if($exposer = $this->request_has_type($request)) {
|
||||||
}
|
return $exposer->rest_request_after_callbacks($response, $handler, $request);
|
||||||
}
|
}
|
||||||
|
} elseif($request->get_method() == 'POST') {
|
||||||
|
if($mapper = $this->request_has_mapper($request)) {
|
||||||
|
return $this->create_mapped_fields( $response, $handler, $request, $mapper );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// default JSON response
|
// default JSON response
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
@ -178,7 +210,7 @@ class Exposers {
|
||||||
return in_array($this->check_class_name($type), $this->types);
|
return in_array($this->check_class_name($type), $this->types);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Return Type with request has type, false otherwise
|
* Return Type if request has type, false otherwise
|
||||||
* @param \WP_REST_Request $request
|
* @param \WP_REST_Request $request
|
||||||
* @return Types\Type|boolean false
|
* @return Types\Type|boolean false
|
||||||
*/
|
*/
|
||||||
|
@ -231,4 +263,80 @@ class Exposers {
|
||||||
}
|
}
|
||||||
return false; // No mapper need, using Tainacan defautls
|
return false; // No mapper need, using Tainacan defautls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add mappers data to translations
|
||||||
|
* @param array $i18n_strings
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function mappers_i18n($i18n_strings) {
|
||||||
|
foreach ($this->mappers as $mapper) {
|
||||||
|
$obj = new $mapper;
|
||||||
|
$i18n_strings[$obj->slug] = $obj->slug; // For url breadcrumb translations
|
||||||
|
$i18n_strings[$obj->name] = $obj->name;
|
||||||
|
}
|
||||||
|
return $i18n_strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return list of registered mappers
|
||||||
|
* @param string $output output format, ARRAY_N or OBJECT
|
||||||
|
*/
|
||||||
|
public function get_mappers($output = ARRAY_N) {
|
||||||
|
$ret = [];
|
||||||
|
switch ($output) {
|
||||||
|
case OBJECT:
|
||||||
|
foreach ($this->mappers as $mapper) {
|
||||||
|
$ret[] = new $mapper;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ARRAY_N:
|
||||||
|
default:
|
||||||
|
return $this->mappers;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param \WP_REST_Response $response
|
||||||
|
* @param \WP_REST_Server $handler
|
||||||
|
* @param \WP_REST_Request $request
|
||||||
|
* @param Mapper $mapper
|
||||||
|
*/
|
||||||
|
public function create_mapped_fields( $response, $handler, $request, $mapper ) {
|
||||||
|
if($response instanceof \WP_REST_Response && $response->get_status() == 201) {
|
||||||
|
$collection_array = $response->get_data();
|
||||||
|
$id = $collection_array['id'];
|
||||||
|
$mapper_fields = $mapper->metadata;
|
||||||
|
if(is_array($mapper_fields) ) {
|
||||||
|
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
||||||
|
foreach ($mapper_fields as $slug => $mapper_field) {
|
||||||
|
if(array_key_exists('core_field', $mapper_field) && $mapper_field['core_field'] != false) continue;
|
||||||
|
|
||||||
|
$field = new \Tainacan\Entities\Field();
|
||||||
|
if(
|
||||||
|
array_key_exists('field_type', $mapper_field) &&
|
||||||
|
$mapper_field['field_type'] != false &&
|
||||||
|
class_exists($mapper_field['field_type'])
|
||||||
|
) {
|
||||||
|
$field->set_field_type($mapper_field['field_type']);
|
||||||
|
} else {
|
||||||
|
$field->set_field_type('Tainacan\Field_Types\Text');
|
||||||
|
}
|
||||||
|
$field->set_name($mapper_field['label']);
|
||||||
|
$field->set_description($mapper_field['URI']);
|
||||||
|
$field->set_exposer_mapping([
|
||||||
|
$mapper->slug => $slug
|
||||||
|
]);
|
||||||
|
$field->set_status('publish');
|
||||||
|
$field->set_collection_id($id);
|
||||||
|
$field->set_slug($slug);
|
||||||
|
if($field->validate()) $Tainacan_Fields->insert($field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -29,15 +29,17 @@ class Dublin_Core extends Mapper {
|
||||||
],
|
],
|
||||||
'date' => [
|
'date' => [
|
||||||
'URI' => 'http://purl.org/dc/elements/1.1/date',
|
'URI' => 'http://purl.org/dc/elements/1.1/date',
|
||||||
'label' => 'Date'
|
'label' => 'Date',
|
||||||
|
'field_type' => 'date'
|
||||||
],
|
],
|
||||||
'description' => [
|
'description' => [
|
||||||
'URI' => 'http://purl.org/dc/elements/1.1/description',
|
'URI' => 'http://purl.org/dc/elements/1.1/description',
|
||||||
'label' => 'Description'
|
'label' => 'Description',
|
||||||
|
'core_field' => 'description'
|
||||||
],
|
],
|
||||||
'format' => [
|
'format' => [
|
||||||
'URI' => 'http://purl.org/dc/elements/1.1/format',
|
'URI' => 'http://purl.org/dc/elements/1.1/format',
|
||||||
'label' => 'Format'
|
'label' => 'Format',
|
||||||
],
|
],
|
||||||
'identifier' => [
|
'identifier' => [
|
||||||
'URI' => 'http://purl.org/dc/elements/1.1/identifier',
|
'URI' => 'http://purl.org/dc/elements/1.1/identifier',
|
||||||
|
@ -69,7 +71,8 @@ class Dublin_Core extends Mapper {
|
||||||
],
|
],
|
||||||
'title' => [
|
'title' => [
|
||||||
'URI' => 'http://purl.org/dc/elements/1.1/title',
|
'URI' => 'http://purl.org/dc/elements/1.1/title',
|
||||||
'label' => 'Title'
|
'label' => 'Title',
|
||||||
|
'core_field' => 'title'
|
||||||
],
|
],
|
||||||
'type' => [
|
'type' => [
|
||||||
'URI' => 'http://purl.org/dc/elements/1.1/type',
|
'URI' => 'http://purl.org/dc/elements/1.1/type',
|
||||||
|
|
|
@ -7,8 +7,42 @@ abstract class Mapper {
|
||||||
public $name = null; // Public name do mapper
|
public $name = null; // Public name do mapper
|
||||||
public $allow_extra_fields = true; // Allow more field to be register
|
public $allow_extra_fields = true; // Allow more field to be register
|
||||||
public $context_url = null; // URL of mapper documentation
|
public $context_url = null; // URL of mapper documentation
|
||||||
public $metadata = false; // array of supported metadata, false for not validade the list
|
|
||||||
|
/**
|
||||||
|
* array of supported metadata, false for not validade the list format:
|
||||||
|
* ['slug'] => [
|
||||||
|
* 'URI' => 'http://...', // URI of the field description
|
||||||
|
* 'label' => 'Label', // Label to show on UI
|
||||||
|
* 'field_type' => 'date', // Tainacan recomended field type, default text
|
||||||
|
* 'core_field' => 'description' // if have a core tainacan field, what?
|
||||||
|
* ['date' => [
|
||||||
|
* 'URI' => 'http://purl.org/dc/elements/1.1/date',
|
||||||
|
* 'label' => 'Date',
|
||||||
|
* 'field_type' => 'date'
|
||||||
|
* ],
|
||||||
|
* 'description' => [
|
||||||
|
* 'URI' => 'http://purl.org/dc/elements/1.1/description',
|
||||||
|
* 'label' => 'Description',
|
||||||
|
* 'core_field' => 'description'
|
||||||
|
* ]]
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $metadata = false;
|
||||||
|
|
||||||
public $prefix = ''; // Tag prefix like "dc:"
|
public $prefix = ''; // Tag prefix like "dc:"
|
||||||
public $sufix = ''; // Tag sufix
|
public $sufix = ''; // Tag sufix
|
||||||
public $header = false; // API response header or file header to be used with
|
public $header = false; // API response header or file header to be used with
|
||||||
|
|
||||||
|
public function _toArray() {
|
||||||
|
return [
|
||||||
|
'slug' => $this->slug,
|
||||||
|
'name' => $this->name,
|
||||||
|
'allow_extra_fields' => $this->allow_extra_fields,
|
||||||
|
'context_url' => $this->context_url,
|
||||||
|
'metadata' => $this->metadata,
|
||||||
|
'prefix' => $this->prefix,
|
||||||
|
'sufix' => $this->sufix,
|
||||||
|
'header' => $this->header
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -12,7 +12,8 @@ class Csv extends Type {
|
||||||
* List of supported mappers
|
* List of supported mappers
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public $mappers = ['Value'];
|
public $mappers = ['Value'];
|
||||||
|
public $slug = 'csv'; // type slug for url safe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -8,7 +8,8 @@ namespace Tainacan\Exposers\Types;
|
||||||
*/
|
*/
|
||||||
class Html extends Type {
|
class Html extends Type {
|
||||||
|
|
||||||
public $mappers = ['Value'];
|
public $mappers = ['Value'];
|
||||||
|
public $slug = 'html'; // type slug for url safe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace Tainacan\Exposers\Types;
|
||||||
class OAI_PMH extends Xml {
|
class OAI_PMH extends Xml {
|
||||||
|
|
||||||
public $mappers = ['Dublin Core'];
|
public $mappers = ['Dublin Core'];
|
||||||
|
public $slug = 'oai-pmh'; // type slug for url safe
|
||||||
|
|
||||||
const XML_OAI_DC_NAMESPACE = "http://www.openarchives.org/OAI/2.0/oai_dc/";
|
const XML_OAI_DC_NAMESPACE = "http://www.openarchives.org/OAI/2.0/oai_dc/";
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace Tainacan\Exposers\Types;
|
||||||
class Txt extends Type {
|
class Txt extends Type {
|
||||||
|
|
||||||
public $mappers = ['Value'];
|
public $mappers = ['Value'];
|
||||||
|
public $slug = 'txt'; // type slug for url safe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,6 +9,8 @@ namespace Tainacan\Exposers\Types;
|
||||||
abstract class Type {
|
abstract class Type {
|
||||||
|
|
||||||
protected $mappers = true; // List of supported mapper, leave true for all
|
protected $mappers = true; // List of supported mapper, leave true for all
|
||||||
|
protected $extension = 'tnc'; // extension sufix for multi operation system compatibility
|
||||||
|
public $slug = ''; // type slug for url safe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change response after api callbacks
|
* Change response after api callbacks
|
||||||
|
@ -19,7 +21,14 @@ abstract class Type {
|
||||||
*/
|
*/
|
||||||
public abstract function rest_request_after_callbacks( $response, $handler, $request );
|
public abstract function rest_request_after_callbacks( $response, $handler, $request );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return list of supported mappers for this type
|
||||||
|
*/
|
||||||
public function get_mappers() {
|
public function get_mappers() {
|
||||||
return apply_filters('tainacan-exporser-type-mappers', $this->mappers, $this);
|
return apply_filters('tainacan-exporser-type-mappers', $this->mappers, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function get_extension() {
|
||||||
|
return $this->extension;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,6 +7,14 @@ namespace Tainacan\Exposers\Types;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Xml extends Type {
|
class Xml extends Type {
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
* @see \Tainacan\Exposers\Types\Type::extension
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $extension = 'xml';
|
||||||
|
public $slug = 'xml'; // type slug for url safe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tainacan;
|
||||||
|
|
||||||
|
class Background_Importer extends Background_Process {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $action = 'import';
|
||||||
|
|
||||||
|
function task($data) {
|
||||||
|
|
||||||
|
$className = $data['class_name'];
|
||||||
|
if (class_exists($className)) {
|
||||||
|
$object = new $className($data);
|
||||||
|
$runned = $object->run();
|
||||||
|
if (false === $runned) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $object->_to_Array();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
|
@ -5,8 +5,12 @@ use Tainacan;
|
||||||
|
|
||||||
class CSV extends Importer {
|
class CSV extends Importer {
|
||||||
|
|
||||||
public function __construct() {
|
protected $manual_mapping = true;
|
||||||
parent::__construct();
|
|
||||||
|
protected $manual_collection = true;
|
||||||
|
|
||||||
|
public function __construct($attributes = array()) {
|
||||||
|
parent::__construct($attributes);
|
||||||
|
|
||||||
$this->set_default_options([
|
$this->set_default_options([
|
||||||
'delimiter' => ','
|
'delimiter' => ','
|
||||||
|
@ -17,7 +21,7 @@ class CSV extends Importer {
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function get_fields(){
|
public function get_source_fields(){
|
||||||
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
||||||
$file->seek(0 );
|
$file->seek(0 );
|
||||||
return $file->fgetcsv( $this->get_option('delimiter') );
|
return $file->fgetcsv( $this->get_option('delimiter') );
|
||||||
|
@ -27,9 +31,9 @@ class CSV extends Importer {
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function process_item( $index ){
|
public function process_item( $index, $collection_definition ){
|
||||||
$processedItem = [];
|
$processedItem = [];
|
||||||
$headers = $this->get_fields();
|
$headers = $this->get_source_fields();
|
||||||
|
|
||||||
// search the index in the file and get values
|
// search the index in the file and get values
|
||||||
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
||||||
|
@ -50,6 +54,8 @@ class CSV extends Importer {
|
||||||
foreach ($headers as $index => $header) {
|
foreach ($headers as $index => $header) {
|
||||||
$processedItem[ $header ] = $values[ $index ];
|
$processedItem[ $header ] = $values[ $index ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->set_progress_current($index+1);
|
||||||
|
|
||||||
return $processedItem;
|
return $processedItem;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +63,7 @@ class CSV extends Importer {
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function get_total_items_from_source(){
|
public function get_progress_total_from_source(){
|
||||||
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
||||||
$file->seek(PHP_INT_MAX);
|
$file->seek(PHP_INT_MAX);
|
||||||
// -1 removing header
|
// -1 removing header
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tainacan;
|
||||||
|
|
||||||
|
class Importer_Handler {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
|
||||||
|
$this->bg_importer = new Background_Importer();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_to_queue($importer_object) {
|
||||||
|
$data = $importer_object->_to_Array();
|
||||||
|
$this->bg_importer->data($data)->save()->dispatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
global $Tainacan_Importer_Handler;
|
||||||
|
$Tainacan_Importer_Handler = new Importer_Handler();
|
||||||
|
|
||||||
|
?>
|
|
@ -5,98 +5,194 @@ use Tainacan\Entities;
|
||||||
|
|
||||||
abstract class Importer {
|
abstract class Importer {
|
||||||
|
|
||||||
private $id;
|
|
||||||
private $processed_items = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* indicates wether this importer will create all the fields collection and set the mapping
|
|
||||||
* without user interaction
|
|
||||||
*
|
|
||||||
* if set to true, user will have the ability to choose to create a new collection upon importing.
|
|
||||||
*
|
|
||||||
* The importer will have to implement the create_fields_and_mapping() method.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
protected $import_structure_and_mapping = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The collection the items are going to be imported to.
|
* The ID for this importer session
|
||||||
|
*
|
||||||
|
* When creating a new importer session via API, an id is returned and used to access this
|
||||||
|
* importer instance in the SESSION array
|
||||||
*
|
*
|
||||||
* @var \Tainacan\Entities\Collection
|
* @var identifier
|
||||||
*/
|
*/
|
||||||
public $collection;
|
private $id;
|
||||||
|
|
||||||
/**
|
|
||||||
* The mapping from the source metadata structure to the Field Ids of the destination collection
|
|
||||||
*
|
|
||||||
* The format is an array where the keys are the field IDs of the destination collection and the
|
|
||||||
* values are the identifier from the source. This coulb be an ID or a string or whatever the importer finds appropriate to http_persistent_handles_clean
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $mapping;
|
|
||||||
private $repository_mapping;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path to the temporary file created when user uploads a file
|
* The path to the temporary file created when user uploads a file
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $tmp_file;
|
protected $tmp_file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The total number of items to be imported.
|
* Wether Tainacan must present the user with an interface to manually map
|
||||||
* @var int
|
* the metadata from the source to the target collection.
|
||||||
*/
|
|
||||||
protected $total_items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* THe number of items to be processes in each step
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $items_per_step = 100;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The index of the item to start the import in the next step.
|
|
||||||
*
|
*
|
||||||
* (items are imported in a series of steps, via ajax, to avoid timeout)
|
* If set to true in the child class, it must implement the method
|
||||||
* @var int
|
* get_source_fields() to return the field found in the source.
|
||||||
|
*
|
||||||
|
* Note that this will only work when importing items to one single collection.
|
||||||
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private $start = 0;
|
protected $manual_mapping = false;
|
||||||
private $inside_step_pointer = 0;
|
|
||||||
|
/**
|
||||||
|
* Wether Tainacan will let the user choose a destination collection.
|
||||||
|
*
|
||||||
|
* If set to true, the API endpoints will handle Collection creation and will assign it to
|
||||||
|
* the importer object using add_collection() method.
|
||||||
|
*
|
||||||
|
* Otherwise, the child importer class must create the collections and add them to the collections property also
|
||||||
|
* using add_collection()
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $manual_collection = true;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The log with everything that happened during the import process. It generates a report afterwards
|
* The total number of iterations to be imported.
|
||||||
|
*
|
||||||
|
* if not possible to calculate, inform 0 (zero) and no progress bar will be displayed.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $progress_total;
|
||||||
|
|
||||||
|
protected $progress_current;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This array holds the structure that the default step 'process_collections' will handle.
|
||||||
|
*
|
||||||
|
* Its an array of the target collections, with their IDs, an identifier from the source, the total number of items to be imported, the mapping array
|
||||||
|
* from the source structure to the ID of the metadata fields in tainacan
|
||||||
|
*
|
||||||
|
* The format of the map is an array where the keys are the metadata IDs of the destination collection and the
|
||||||
|
* values are the identifier from the source. This could be an ID or a string or whatever the importer finds appropriate to handle
|
||||||
|
*
|
||||||
|
* The source_id can be anyhting you like, that helps you relate this collection to your source.
|
||||||
|
*
|
||||||
|
* Example of the structure of this propery for one collection:
|
||||||
|
* 0 => [
|
||||||
|
* 'id' => 12,
|
||||||
|
* 'map' => [
|
||||||
|
* 30 => 'column1'
|
||||||
|
* 31 => 'column2'
|
||||||
|
* ],
|
||||||
|
* 'total_items' => 1234,
|
||||||
|
* 'source_id' => 55
|
||||||
|
* ],
|
||||||
|
*
|
||||||
|
* use add_collection() and remove_collection() to interact with thiis array.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $collections = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the options for the importer. Each importer might use this property to save
|
||||||
|
* their own specific option
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public $logs = [];
|
|
||||||
|
|
||||||
private $options = [];
|
private $options = [];
|
||||||
|
|
||||||
private $default_options = [];
|
/**
|
||||||
|
* Stores the default options for the importer options
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $default_options = [];
|
||||||
|
|
||||||
private $accpets = [
|
private $accpets = [
|
||||||
'file' => true,
|
'file' => true,
|
||||||
'url' => false,
|
'url' => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
private $is_repository = false;
|
/**
|
||||||
|
* Declares what are the steps the importer will run, in the right order.
|
||||||
private $steps = [];
|
*
|
||||||
|
* By default, there is only one step, and the callback is the process_collections method
|
||||||
|
* that process items for the collections in the collections array.
|
||||||
|
*
|
||||||
|
* Child classes may declare as many steps as they want and can keep this default step to use
|
||||||
|
* this method for import the items. But it is optional.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $steps = [
|
||||||
|
[
|
||||||
|
'name' => 'Import Items',
|
||||||
|
'callback' => 'process_collections'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transients is used to store temporary data to be used accross multiple requests
|
||||||
|
*
|
||||||
|
* Add and remove transient data using add_transient() and delete_transient() methods
|
||||||
|
*
|
||||||
|
* Transitens can be strings, numbers or arrays. Avoid storing objects.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $transients = [];
|
||||||
|
|
||||||
private $current_step = 0;
|
private $current_step = 0;
|
||||||
|
|
||||||
|
private $in_step_count = 0;
|
||||||
|
|
||||||
|
private $current_collection = 0;
|
||||||
|
|
||||||
|
private $current_collection_item = 0;
|
||||||
|
|
||||||
private $url = '';
|
private $url = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of attributes that are saved in DB and that are used to
|
||||||
|
* reconstruct the object
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $array_attributes = [
|
||||||
|
'url',
|
||||||
|
'current_collection_item',
|
||||||
|
'current_collection',
|
||||||
|
'in_step_count',
|
||||||
|
'current_step',
|
||||||
|
'transients',
|
||||||
|
'options',
|
||||||
|
'collections',
|
||||||
|
'tmp_file'
|
||||||
|
];
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct($attributess = array()) {
|
||||||
if (!session_id()) {
|
if (!session_id()) {
|
||||||
@session_start();
|
@session_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->id = uniqid();
|
$this->id = uniqid();
|
||||||
$_SESSION['tainacan_importer'][$this->get_id()] = $this;
|
$_SESSION['tainacan_importer'][$this->get_id()] = $this;
|
||||||
|
|
||||||
|
if (!empty($attributess)) {
|
||||||
|
foreach ($attributess as $attr => $value) {
|
||||||
|
$method = 'set_' . $attr;
|
||||||
|
if (method_exists($this, $method)) {
|
||||||
|
$this->$method($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function _to_Array() {
|
||||||
|
$return = [];
|
||||||
|
foreach ($this->array_attributes as $attr) {
|
||||||
|
$method = 'get_' . $attr;
|
||||||
|
$return[$attr] = $this->$method();
|
||||||
|
}
|
||||||
|
$return['class_name'] = get_class($this);
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// Getters and setters
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
@ -133,82 +229,133 @@ abstract class Importer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function get_current_step() {
|
||||||
* @return array Mapping
|
return $this->current_step;
|
||||||
*/
|
}
|
||||||
public function get_mapping(){
|
|
||||||
return $this->mapping;
|
public function set_current_step($value) {
|
||||||
|
$this->current_step = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_in_step_count() {
|
||||||
|
return $this->in_step_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_in_step_count($value) {
|
||||||
|
$this->in_step_count = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_current_collection() {
|
||||||
|
return $this->current_collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_current_collection($value) {
|
||||||
|
$this->current_collection = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_current_collection_item() {
|
||||||
|
return $this->current_collection_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_current_collection_item($value) {
|
||||||
|
$this->current_collection_item = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_tmp_file(){
|
||||||
|
return $this->tmp_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function set_tmp_file($filepath){
|
||||||
* @return array Array with ids inserted in Tainacan
|
$this->tmp_file = $filepath;
|
||||||
*/
|
|
||||||
public function get_processed_items(){
|
|
||||||
return $this->processed_items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function get_progress_current() {
|
||||||
* @return array the last index from source
|
return $this->progress_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_progress_current($value) {
|
||||||
|
$this->progress_current = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_collections() {
|
||||||
|
return $this->collections;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_collections($value) {
|
||||||
|
$this->collections = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the options for this importer, including default values for options
|
||||||
|
* that were not set yet.
|
||||||
|
* @return array Importer options
|
||||||
*/
|
*/
|
||||||
public function get_logs(){
|
public function get_options() {
|
||||||
return $this->logs;
|
return array_merge($this->default_options, $this->options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Tainacan\Entities\Collection $collection
|
* Set the options array
|
||||||
*/
|
* @param array $options
|
||||||
public function set_collection( Entities\Collection $collection ){
|
*/
|
||||||
$this->collection = $collection;
|
public function set_options($options) {
|
||||||
|
$this->options = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the default options values.
|
||||||
|
*
|
||||||
|
* Must be called from the __construct method of the child importer class to set default values.
|
||||||
|
*
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
protected function set_default_options($options) {
|
||||||
|
$this->default_options = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function set_steps($steps) {
|
||||||
|
$this->steps = $steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function get_steps() {
|
||||||
* save an associative array with tainacan field id as index and field from source as value
|
return $this->steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the total progress number to calculate progress
|
||||||
*
|
*
|
||||||
* @param array $mapping Mapping importer-fields
|
* @return int Total of items
|
||||||
*/
|
*/
|
||||||
public function set_mapping( $mapping){
|
public function get_progress_total() {
|
||||||
if(!empty($mapping))
|
if ( !isset( $this->progress_total ) ) {
|
||||||
{
|
if ( method_exists($this, 'get_progress_total_from_source') ) {
|
||||||
$this->mapping = $mapping;
|
$this->progress_total = $this->get_progress_total_from_source();
|
||||||
}
|
} else {
|
||||||
}
|
$this->progress_total = 0;
|
||||||
|
}
|
||||||
public function set_repository_mapping( $mapping, $item_id ){
|
|
||||||
if(!empty($mapping) && !empty($item_id))
|
}
|
||||||
{
|
return $this->progress_total;
|
||||||
$this->repository_mapping[$item_id] = $mapping;
|
}
|
||||||
}else return false;
|
|
||||||
}
|
private function get_transients() {
|
||||||
|
return $this->transients;
|
||||||
public function get_repository_mapping($item_id)
|
}
|
||||||
{
|
|
||||||
if(!empty($item_id))
|
private function set_transients(array $data) {
|
||||||
{
|
$this->transients = $data;
|
||||||
return $this->repository_mapping[$item_id];
|
}
|
||||||
}else return false;
|
|
||||||
}
|
////////////////////////////////////
|
||||||
|
// Utilities
|
||||||
/**
|
|
||||||
* set how many items should be processes in each step
|
|
||||||
*
|
|
||||||
* @param $size The total of items
|
|
||||||
*/
|
|
||||||
public function set_items_per_step( $size ){
|
|
||||||
$this->items_per_step = $size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $start the first index to init the process
|
|
||||||
*/
|
|
||||||
public function set_start( $start ){
|
|
||||||
$this->start = $start;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $file File to be managed by importer
|
* @param $file File to be managed by importer
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function set_file( $file ){
|
public function add_file( $file ){
|
||||||
$new_file = $this->upload_file( $file );
|
$new_file = $this->upload_file( $file );
|
||||||
if ( is_numeric( $new_file ) ) {
|
if ( is_numeric( $new_file ) ) {
|
||||||
$this->tmp_file = get_attached_file( $new_file );
|
$this->tmp_file = get_attached_file( $new_file );
|
||||||
|
@ -216,22 +363,8 @@ abstract class Importer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function set_inside_step_pointer($step_pointer)
|
|
||||||
{
|
|
||||||
if(is_numeric($step_pointer) && $step_pointer >= 0)
|
|
||||||
{
|
|
||||||
$this->inside_step_pointer = $step_pointer;
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
$this->inside_step_pointer = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_inside_step_pointer()
|
|
||||||
{
|
|
||||||
return $this->inside_step_pointer;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* log the actions from importer
|
* log the actions from importer
|
||||||
*
|
*
|
||||||
|
@ -241,6 +374,22 @@ abstract class Importer {
|
||||||
public function add_log($type, $message ){
|
public function add_log($type, $message ){
|
||||||
$this->logs[] = [ 'type' => $type, 'message' => $message ];
|
$this->logs[] = [ 'type' => $type, 'message' => $message ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function add_collection(array $collection) {
|
||||||
|
if (isset($collection['id'])) {
|
||||||
|
$this->remove_collection($collection['id']);
|
||||||
|
$this->collections[] = $collection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove_collection($col_id) {
|
||||||
|
foreach ($this->get_collections() as $index => $col) {
|
||||||
|
if ($col['id'] == $col_id) {
|
||||||
|
unset($this->collections[$index]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* internal function to upload the file
|
* internal function to upload the file
|
||||||
|
@ -264,59 +413,13 @@ abstract class Importer {
|
||||||
*/
|
*/
|
||||||
public function fetch_from_remote( $url ){
|
public function fetch_from_remote( $url ){
|
||||||
$tmp = wp_remote_get( $url );
|
$tmp = wp_remote_get( $url );
|
||||||
if( isset( $tmp['body'] ) ){
|
if( !is_wp_error($tmp) && isset( $tmp['body'] ) ){
|
||||||
$file = fopen( $this->get_id().'.txt', 'w' );
|
$file = fopen( $this->get_id().'.txt', 'w' );
|
||||||
fwrite( $file, $tmp['body'] );
|
fwrite( $file, $tmp['body'] );
|
||||||
fclose( $file );
|
fclose( $file );
|
||||||
return $this->set_file( $this->get_id().'.txt' );
|
return $this->add_file( $this->get_id().'.txt' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* get the fields of file/url to allow mapping
|
|
||||||
* should return an array
|
|
||||||
*
|
|
||||||
* @return array $fields_source the fields from the source
|
|
||||||
*/
|
|
||||||
abstract public function get_fields();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get values for a single item
|
|
||||||
*
|
|
||||||
* @param $index
|
|
||||||
* @return array with field_source's as the index and values for the
|
|
||||||
* item
|
|
||||||
*
|
|
||||||
* Ex: [ 'Field1' => 'value1', 'Field2' => [ 'value2','value3' ]
|
|
||||||
*/
|
|
||||||
abstract public function process_item( $index );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return the all items found
|
|
||||||
*
|
|
||||||
* @return int Total of items
|
|
||||||
*/
|
|
||||||
public function get_total_items() {
|
|
||||||
if ( !isset( $this->total_items ) ) {
|
|
||||||
$this->total_items = $this->get_total_items_from_source();
|
|
||||||
}
|
|
||||||
return $this->total_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method implemented by the child importer class to return the number of items to be imported
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
abstract public function get_total_items_from_source();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the options for this importer, including default values for options
|
|
||||||
* that were not set yet.
|
|
||||||
* @return array Importer options
|
|
||||||
*/
|
|
||||||
public function get_options() {
|
|
||||||
return array_merge($this->default_options, $this->options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets one option from the options array.
|
* Gets one option from the options array.
|
||||||
|
@ -331,25 +434,6 @@ abstract class Importer {
|
||||||
return isset($options[$key]) ? $options[$key] : '';
|
return isset($options[$key]) ? $options[$key] : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default options values.
|
|
||||||
*
|
|
||||||
* Must be called from the __construct method of the child importer class to set default values.
|
|
||||||
*
|
|
||||||
* @param array $options
|
|
||||||
*/
|
|
||||||
protected function set_default_options($options) {
|
|
||||||
$this->default_options = $options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the options array
|
|
||||||
* @param array $options
|
|
||||||
*/
|
|
||||||
public function set_options($options) {
|
|
||||||
$this->options = $options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new method accepeted by the importer
|
* Adds a new method accepeted by the importer
|
||||||
*
|
*
|
||||||
|
@ -366,38 +450,6 @@ abstract class Importer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function get_start()
|
|
||||||
{
|
|
||||||
return $this->start;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function get_items_per_step()
|
|
||||||
{
|
|
||||||
return $this->items_per_step;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets importer as repository importer
|
|
||||||
*/
|
|
||||||
public function set_repository()
|
|
||||||
{
|
|
||||||
$this->is_repository = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set_steps($steps)
|
|
||||||
{
|
|
||||||
$this->steps =$steps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function is_finished()
|
|
||||||
{
|
|
||||||
if($this->current_step >= count($this->steps))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Removes method accepeted by the importer
|
* Removes method accepeted by the importer
|
||||||
*
|
*
|
||||||
|
@ -414,59 +466,180 @@ abstract class Importer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function add_transient($key, $data) {
|
||||||
* process a limited size of items
|
$this->transients[$key] = $data;
|
||||||
*
|
}
|
||||||
* @param int $start the index of the item to start processing from
|
|
||||||
*/
|
public function delete_transient($key) {
|
||||||
public function process( $start ){
|
if (isset($this->transients[$key]))
|
||||||
|
unset($this->transients[$key]);
|
||||||
$end = $start + $this->items_per_step;
|
}
|
||||||
|
|
||||||
|
public function get_transient($key) {
|
||||||
|
if (isset($this->transients[$key]))
|
||||||
|
return $this->transients[$key];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
while ( $start < $end && count( $this->get_processed_items() ) < $this->get_total_items() ) {
|
public function is_finished()
|
||||||
$processed_item = $this->process_item( $start );
|
{
|
||||||
if( $processed_item) {
|
if($this->current_step >= count($this->steps))
|
||||||
$this->insert( $start, $processed_item );
|
{
|
||||||
} else {
|
return true;
|
||||||
$this->add_log('error', 'failed on item '.$start );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$start++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->set_start($start);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// Abstract methods
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the fields of file/url to allow mapping
|
||||||
|
* should return an array
|
||||||
|
*
|
||||||
|
* Used when $manual_mapping is set to true, to build the mapping interface
|
||||||
|
*
|
||||||
|
* @return array $fields_source the fields from the source
|
||||||
|
*/
|
||||||
|
public function get_source_fields() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get values for a single item
|
||||||
|
*
|
||||||
|
* @param $index
|
||||||
|
* @return array with field_source's as the index and values for the
|
||||||
|
* item
|
||||||
|
*
|
||||||
|
* Ex: [ 'Field1' => 'value1', 'Field2' => [ 'value2','value3' ]
|
||||||
|
*/
|
||||||
|
abstract public function process_item( $index, $collection_id );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method implemented by the child importer class to return the total number of interations the importer must run
|
||||||
|
*
|
||||||
|
* Used to build the progress bar
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function get_progress_total_from_source() {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Core methods
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process an item from the collections queue
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function process_collections() {
|
||||||
|
|
||||||
|
$current_collection = $this->get_current_collection();
|
||||||
|
$collections = $this->get_collections();
|
||||||
|
$collection_definition = isset($collections[$current_collection]) ? $collections[$current_collection] : false;
|
||||||
|
$current_collection_item = $this->get_current_collection_item();
|
||||||
|
|
||||||
|
$processed_item = $this->process_item( $current_collection_item, $collection_definition );
|
||||||
|
if( $processed_item) {
|
||||||
|
$this->insert( $processed_item, $current_collection );
|
||||||
|
} else {
|
||||||
|
$this->add_log('error', 'failed on item '. $start );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->next_item();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function next_item() {
|
||||||
|
|
||||||
|
$current_collection = $this->get_current_collection();
|
||||||
|
$current_collection_item = $this->get_current_collection_item();
|
||||||
|
$collections = $this->get_collections();
|
||||||
|
$collection = $collections[$current_collection];
|
||||||
|
|
||||||
|
$current_collection_item ++;
|
||||||
|
$this->set_current_collection_item($current_collection_item);
|
||||||
|
|
||||||
|
if ($current_collection_item >= $collection['total_items']) {
|
||||||
|
return $this->next_collection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $current_collection_item;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function next_collection() {
|
||||||
|
|
||||||
|
$current_collection = $this->get_current_collection();
|
||||||
|
$collections = $this->get_collections();
|
||||||
|
|
||||||
|
$this->set_current_collection_item(0);
|
||||||
|
|
||||||
|
$current_collection ++;
|
||||||
|
|
||||||
|
if (isset($collections[$current_collection])) {
|
||||||
|
$this->set_current_collection($current_collection);
|
||||||
|
return $current_collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function next_step() {
|
||||||
|
|
||||||
|
$current_step = $this->get_current_step();
|
||||||
|
$steps = $this->get_steps();
|
||||||
|
|
||||||
|
$current_step ++;
|
||||||
|
$this->set_current_step($current_step);
|
||||||
|
|
||||||
|
if (isset($steps[$current_step])) {
|
||||||
|
return $current_step;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* insert processed item from source to Tainacan
|
* insert processed item from source to Tainacan
|
||||||
*
|
*
|
||||||
* @param int $index the source id unique for the item
|
|
||||||
* @param array $processed_item Associative array with field source's as index with
|
* @param array $processed_item Associative array with field source's as index with
|
||||||
* its value or values
|
* its value or values
|
||||||
* @return Tainacan\Entities\Item Item inserted
|
* @return Tainacan\Entities\Item Item inserted
|
||||||
*/
|
*/
|
||||||
public function insert( $index, $processed_item ){
|
public function insert( $processed_item, $collection_index ) {
|
||||||
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
|
||||||
|
$collections = $this->get_collections();
|
||||||
|
$collection_definition = isset($collections[$collection_index]) ? $collections[$collection_index] : false;
|
||||||
|
if ( !$collection_definition || !is_array($collection_definition) || !isset($collection_definition['id']) || !isset($collection_definition['map']) ) {
|
||||||
|
$this->add_log('error','Collection misconfigured');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$collection = \Tainacan\Repositories\Collections::get_instance()->fetch($collection_definition['id']);
|
||||||
|
|
||||||
|
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
||||||
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
|
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
|
||||||
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
|
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
|
||||||
|
|
||||||
$isUpdate = ( is_array( $this->processed_items ) && isset( $this->processed_items[ $index ] ) )
|
$item = new Entities\Item();
|
||||||
? $this->processed_items[ $index ] : 0;
|
|
||||||
$item = new Entities\Item( $isUpdate );
|
|
||||||
$itemMetadataArray = [];
|
$itemMetadataArray = [];
|
||||||
|
|
||||||
if( !isset( $this->mapping ) ){
|
|
||||||
$this->add_log('error','Mapping is not set');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( is_array( $processed_item ) ){
|
if( is_array( $processed_item ) ){
|
||||||
foreach ( $processed_item as $field_source => $values ){
|
foreach ( $processed_item as $field_source => $values ){
|
||||||
$tainacan_field_id = array_search( $field_source, $this->mapping );
|
$tainacan_field_id = array_search( $field_source, $collection_definition['map'] );
|
||||||
$field = $Tainacan_Fields->fetch( $tainacan_field_id );
|
$field = $Tainacan_Fields->fetch( $tainacan_field_id );
|
||||||
|
|
||||||
if( $field instanceof Entities\Field ){
|
if( $field instanceof Entities\Field ){
|
||||||
$singleItemMetadata = new Entities\Item_Metadata_Entity( $item, $field);
|
$singleItemMetadata = new Entities\Item_Metadata_Entity( $item, $field); // *empty item will be replaced by inserted in the next foreach
|
||||||
$singleItemMetadata->set_value( $values );
|
$singleItemMetadata->set_value( $values );
|
||||||
$itemMetadataArray[] = $singleItemMetadata;
|
$itemMetadataArray[] = $singleItemMetadata;
|
||||||
}
|
}
|
||||||
|
@ -474,8 +647,8 @@ abstract class Importer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !empty( $itemMetadataArray ) && $this->collection instanceof Entities\Collection ){
|
if( !empty( $itemMetadataArray ) && $collection instanceof Entities\Collection ){
|
||||||
$item->set_collection( $this->collection );
|
$item->set_collection( $collection );
|
||||||
|
|
||||||
if( $item->validate() ){
|
if( $item->validate() ){
|
||||||
$insertedItem = $Tainacan_Items->insert( $item );
|
$insertedItem = $Tainacan_Items->insert( $item );
|
||||||
|
@ -485,37 +658,37 @@ abstract class Importer {
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ( $itemMetadataArray as $itemMetadata ) {
|
foreach ( $itemMetadataArray as $itemMetadata ) {
|
||||||
$itemMetadata->set_item( $insertedItem );
|
$itemMetadata->set_item( $insertedItem ); // *I told you
|
||||||
|
|
||||||
if( $itemMetadata->validate() ){
|
if( $itemMetadata->validate() ){
|
||||||
$result = $Tainacan_Item_Metadata->insert( $itemMetadata );
|
$result = $Tainacan_Item_Metadata->insert( $itemMetadata );
|
||||||
} else {
|
} else {
|
||||||
$this->add_log( 'error', 'Item ' . $index . ' on field '. $itemMetadata->get_field()->get_name()
|
$this->add_log( 'error', 'Item ' . $insertedItem->get_id() . ' on field '. $itemMetadata->get_field()->get_name()
|
||||||
.' has error ' . $itemMetadata->get_errors() );
|
.' has error ' . $itemMetadata->get_errors() );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( $result ){
|
if( $result ){
|
||||||
$values = ( is_array( $itemMetadata->get_value() ) ) ? implode( PHP_EOL, $itemMetadata->get_value() ) : $itemMetadata->get_value();
|
$values = ( is_array( $itemMetadata->get_value() ) ) ? implode( PHP_EOL, $itemMetadata->get_value() ) : $itemMetadata->get_value();
|
||||||
$this->add_log( 'success', 'Item ' . $index .
|
$this->add_log( 'success', 'Item ' . $insertedItem->get_id() .
|
||||||
' has inserted the values: ' . $values . ' on field: ' . $itemMetadata->get_field()->get_name() );
|
' has inserted the values: ' . $values . ' on field: ' . $itemMetadata->get_field()->get_name() );
|
||||||
} else {
|
} else {
|
||||||
$this->add_log( 'error', 'Item ' . $index . ' has an error' );
|
$this->add_log( 'error', 'Item ' . $insertedItem->get_id() . ' has an error' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$insertedItem->set_status('publish' );
|
$insertedItem->set_status('publish' );
|
||||||
|
|
||||||
// inserted the id on processed item with its index as array index
|
|
||||||
$this->processed_items[ $index ] = $insertedItem->get_id();
|
|
||||||
if($insertedItem->validate()) {
|
if($insertedItem->validate()) {
|
||||||
$insertedItem = $Tainacan_Items->update( $insertedItem );
|
$insertedItem = $Tainacan_Items->update( $insertedItem );
|
||||||
} else {
|
} else {
|
||||||
$this->add_log( 'error', 'Item ' . $index . ': ' . $insertedItem->get_errors()[0]['title'] ); // TODO add the $item->get_errors() array
|
//error_log(print_r($insertedItem->get_errors(), true));
|
||||||
|
//$this->add_log( 'error', 'Item ' . $index . ': ' . $insertedItem->get_errors()[0]['title'] ); // TODO add the $item->get_errors() array
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $insertedItem;
|
return $insertedItem;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$this->add_log( 'error', 'Collection not set');
|
$this->add_log( 'error', 'Collection not set');
|
||||||
return false;
|
return false;
|
||||||
|
@ -524,47 +697,35 @@ abstract class Importer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* run the process
|
* runs one iteration
|
||||||
*/
|
*/
|
||||||
public function run(){
|
public function run(){
|
||||||
if($this->is_repository && $this->current_step < count($this->steps))
|
|
||||||
{
|
|
||||||
//$process_name = key($this->steps);
|
|
||||||
$function_name = current($this->steps);
|
|
||||||
$inside_step_pointer = $this->{$function_name}();//If unlike numeric this means that still there is stuff to process
|
|
||||||
|
|
||||||
if($inside_step_pointer === false || (!is_numeric($inside_step_pointer) || $inside_step_pointer < 0))
|
if ($this->is_finished()) {
|
||||||
{
|
return false;
|
||||||
//Move on to the next step
|
}
|
||||||
next($this->steps);
|
|
||||||
$this->current_step++;
|
$steps = $this->get_steps();
|
||||||
$this->set_inside_step_pointer(0);
|
$current_step = $this->get_current_step();
|
||||||
}else if(is_numeric($inside_step_pointer) && $inside_step_pointer > 0)
|
$method_name = $steps[$current_step]['callback'];
|
||||||
{
|
|
||||||
$this->set_inside_step_pointer($inside_step_pointer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( ( !isset($this->collection) || ! $this->collection instanceof Entities\Collection ) && $this->import_structure_and_mapping ) {
|
|
||||||
$new_collection = new Entities\Collection();
|
|
||||||
$new_collection->set_name('New Imported Collection');
|
|
||||||
$new_collection->set_status('publish');
|
|
||||||
$new_collection->validate();
|
|
||||||
$new_collection = Tainacan\Repositories\Collections::get_instance()->insert($new_collection);
|
|
||||||
|
|
||||||
$this->set_collection($new_collection);
|
if (method_exists($this, $method_name)) {
|
||||||
|
$result = $this->$method_name();
|
||||||
if (!method_exists($this, 'create_fields_and_mapping')) {
|
} else {
|
||||||
throw new Exception('Importers with import_structure_and_mapping true must implement create_fields_and_mapping method');
|
$this->add_log( 'error', 'Callback not found for step ' . $steps[$current_step]['name']);
|
||||||
}
|
$result = false;
|
||||||
|
}
|
||||||
$this->create_fields_and_mapping();
|
if($result === false || (!is_numeric($result) || $result < 0)) {
|
||||||
|
//Move on to the next step
|
||||||
}
|
$this->set_in_step_count(0);
|
||||||
|
$return = $this->next_step();
|
||||||
$this->process( $this->start );
|
} else if(is_numeric($result) && $result > 0) {
|
||||||
return sizeof($this->get_processed_items());
|
$this->set_in_step_count($result);
|
||||||
}
|
$return = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,13 +8,15 @@
|
||||||
|
|
||||||
namespace Tainacan\Importer;
|
namespace Tainacan\Importer;
|
||||||
|
|
||||||
class Old_Tainacan extends Importer
|
class Old_Tainacan extends Importer{
|
||||||
{
|
|
||||||
|
protected $manual_mapping = true;
|
||||||
|
|
||||||
|
protected $manual_collection = true;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->set_repository();
|
|
||||||
$this->set_steps($this->steps);
|
|
||||||
$this->remove_import_method('file');
|
$this->remove_import_method('file');
|
||||||
$this->add_import_method('url');
|
$this->add_import_method('url');
|
||||||
$this->tainacan_api_address = "/wp-json/tainacan/v1";
|
$this->tainacan_api_address = "/wp-json/tainacan/v1";
|
||||||
|
@ -30,15 +32,39 @@ class Old_Tainacan extends Importer
|
||||||
'socialdb_property_fixed_attachments'
|
'socialdb_property_fixed_attachments'
|
||||||
],
|
],
|
||||||
$steps = [
|
$steps = [
|
||||||
'Creating all categories' => 'create_categories',
|
[
|
||||||
'Create empty collections' => 'create_collections',
|
'name' => 'Create categories, collections and metadata',
|
||||||
'Creating relationships metadata' => 'create_relationships_meta',
|
'callback' => 'create_structure'
|
||||||
'Create repository metadata' => 'treat_repo_meta',
|
],
|
||||||
'Create collections metadata' => 'treat_collection_metas',
|
[
|
||||||
'Create collections items' => 'create_collection_items',
|
'name' => 'Import Items',
|
||||||
"Finishing" => 'clear'
|
'callback' => 'process_collections'
|
||||||
], $tainacan_api_address, $wordpress_api_address;
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Finishing',
|
||||||
|
'callback' => 'clear'
|
||||||
|
]
|
||||||
|
], $tainacan_api_address, $wordpress_api_address, $actual_collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create structure tainacan
|
||||||
|
*/
|
||||||
|
public function create_structure(){
|
||||||
|
$this->create_categories();
|
||||||
|
$this->create_collections();
|
||||||
|
$this->create_relationships_meta();
|
||||||
|
$this->treat_repo_meta();
|
||||||
|
$this->treat_collection_metas();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper method to set the actual collection in loop
|
||||||
|
*/
|
||||||
|
public function set_actual_collection($collection){
|
||||||
|
$this->actual_collection = $collection;
|
||||||
|
}
|
||||||
|
|
||||||
public function create_categories()
|
public function create_categories()
|
||||||
{
|
{
|
||||||
|
@ -53,8 +79,10 @@ class Old_Tainacan extends Importer
|
||||||
|
|
||||||
$categories_array = $this->remove_same_name($categories_array);
|
$categories_array = $this->remove_same_name($categories_array);
|
||||||
|
|
||||||
list($inside_step_pointer, $end) = $this->get_begin_end($categories_array);
|
// list($inside_step_pointer, $end) = $this->get_begin_end($categories_array);
|
||||||
if($inside_step_pointer === false) return false;
|
// if($inside_step_pointer === false) return false;
|
||||||
|
$inside_step_pointer = 0;
|
||||||
|
$end = ( $categories_array ) ? count( $categories_array) : 0;
|
||||||
|
|
||||||
$created_categories = [];
|
$created_categories = [];
|
||||||
while($inside_step_pointer < $end)
|
while($inside_step_pointer < $end)
|
||||||
|
@ -96,8 +124,10 @@ class Old_Tainacan extends Importer
|
||||||
$created_collections = [];
|
$created_collections = [];
|
||||||
if($collections_array)
|
if($collections_array)
|
||||||
{
|
{
|
||||||
list($inside_step_pointer, $end) = $this->get_begin_end($collections_array);
|
// list($inside_step_pointer, $end) = $this->get_begin_end($collections_array);
|
||||||
if($inside_step_pointer === false) return false;
|
// if($inside_step_pointer === false) return false;
|
||||||
|
$inside_step_pointer = 0;
|
||||||
|
$end = ( $collections_array ) ? count( $collections_array) : 0;
|
||||||
|
|
||||||
while($inside_step_pointer < $end)
|
while($inside_step_pointer < $end)
|
||||||
{
|
{
|
||||||
|
@ -192,17 +222,19 @@ class Old_Tainacan extends Importer
|
||||||
$created_categories = $this->read_from_file("categories");
|
$created_categories = $this->read_from_file("categories");
|
||||||
$relationships = $this->read_from_file("relationships");
|
$relationships = $this->read_from_file("relationships");
|
||||||
|
|
||||||
list($inside_step_pointer, $end) = $this->get_begin_end($created_collections);
|
// list($inside_step_pointer, $end) = $this->get_begin_end($created_collections);
|
||||||
if($inside_step_pointer === false) return false;
|
// if($inside_step_pointer === false) return false;
|
||||||
|
$inside_step_pointer = 0;
|
||||||
|
$end = ( $created_collections ) ? count( $created_collections) : 0;
|
||||||
|
|
||||||
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
||||||
$Fields_Repository = \Tainacan\Repositories\Fields::get_instance();
|
$Fields_Repository = \Tainacan\Repositories\Fields::get_instance();
|
||||||
$Repository_Collections = \Tainacan\Repositories\Collections::get_instance();
|
$Repository_Collections = \Tainacan\Repositories\Collections::get_instance();
|
||||||
|
|
||||||
for($i = 0; $i < $inside_step_pointer; $i++)
|
//for($i = 0; $i < $inside_step_pointer; $i++)
|
||||||
{
|
// {
|
||||||
next($created_collections);
|
// next($created_collections);
|
||||||
}
|
// }
|
||||||
|
|
||||||
while($inside_step_pointer < $end)
|
while($inside_step_pointer < $end)
|
||||||
{
|
{
|
||||||
|
@ -210,13 +242,19 @@ class Old_Tainacan extends Importer
|
||||||
$new_collection_id = $collection_info['new_id'];
|
$new_collection_id = $collection_info['new_id'];
|
||||||
$old_collection_id = key($created_collections);
|
$old_collection_id = key($created_collections);
|
||||||
$collection = $Repository_Collections->fetch($new_collection_id);
|
$collection = $Repository_Collections->fetch($new_collection_id);
|
||||||
$this->set_collection($collection);
|
$this->set_actual_collection($collection);
|
||||||
|
|
||||||
$file_fields = $this->get_collection_fields($old_collection_id);
|
$file_fields = $this->get_collection_fields($old_collection_id);
|
||||||
|
|
||||||
$mapping = $this->create_collection_meta($file_fields, $Fields_Repository, $Tainacan_Fields, $created_repository_fields, $created_categories, $relationships);
|
$mapping = $this->create_collection_meta($file_fields, $Fields_Repository, $Tainacan_Fields, $created_repository_fields, $created_categories, $relationships);
|
||||||
|
|
||||||
$this->set_repository_mapping($mapping, $old_collection_id);
|
$this->add_collection([
|
||||||
|
'id' => $new_collection_id,
|
||||||
|
'map' => $mapping,
|
||||||
|
'total_items' => $this->get_total_items_from_source( $old_collection_id )
|
||||||
|
]);
|
||||||
|
|
||||||
|
// $this->set_repository_mapping($mapping, $old_collection_id);
|
||||||
next($created_collections);
|
next($created_collections);
|
||||||
$inside_step_pointer++;
|
$inside_step_pointer++;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +304,7 @@ class Old_Tainacan extends Importer
|
||||||
$mapping[$new_id] = $created_repository_fields[$old_field_id]['name'];
|
$mapping[$new_id] = $created_repository_fields[$old_field_id]['name'];
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
$fields = $Tainacan_Fields->fetch_by_collection( $this->collection, [], 'OBJECT' );
|
$fields = $Tainacan_Fields->fetch_by_collection( $this->actual_collection, [], 'OBJECT' );
|
||||||
|
|
||||||
foreach ($fields as $field)
|
foreach ($fields as $field)
|
||||||
{
|
{
|
||||||
|
@ -353,7 +391,7 @@ class Old_Tainacan extends Importer
|
||||||
$newField->set_collection_id('default');
|
$newField->set_collection_id('default');
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
$newField->set_collection($this->collection);
|
$newField->set_collection($this->actual_collection);
|
||||||
}
|
}
|
||||||
}else //Set compound as field parent
|
}else //Set compound as field parent
|
||||||
{
|
{
|
||||||
|
@ -399,7 +437,7 @@ class Old_Tainacan extends Importer
|
||||||
$new_collection_id = $collection_info['new_id'];
|
$new_collection_id = $collection_info['new_id'];
|
||||||
$old_collection_id = key($created_collections);
|
$old_collection_id = key($created_collections);
|
||||||
$collection = $Repository_Collections->fetch($new_collection_id);
|
$collection = $Repository_Collections->fetch($new_collection_id);
|
||||||
$this->set_collection($collection);
|
$this->set_actual_collection($collection);
|
||||||
|
|
||||||
$mapping = $this->get_repository_mapping($old_collection_id);
|
$mapping = $this->get_repository_mapping($old_collection_id);
|
||||||
$this->set_mapping($mapping);
|
$this->set_mapping($mapping);
|
||||||
|
@ -481,7 +519,7 @@ class Old_Tainacan extends Importer
|
||||||
|
|
||||||
private function get_begin_end($items)
|
private function get_begin_end($items)
|
||||||
{
|
{
|
||||||
$inside_step_pointer = $this->get_inside_step_pointer();
|
$inside_step_pointer = $this->get_in_step_count();
|
||||||
$total_items = count($items);
|
$total_items = count($items);
|
||||||
|
|
||||||
if($inside_step_pointer >= $total_items)
|
if($inside_step_pointer >= $total_items)
|
||||||
|
@ -489,7 +527,7 @@ class Old_Tainacan extends Importer
|
||||||
return [false, false];
|
return [false, false];
|
||||||
}
|
}
|
||||||
|
|
||||||
$end = $this->get_inside_step_pointer() + $this->get_items_per_step();
|
$end = $this->get_in_step_count() + $this->get_items_per_step();
|
||||||
if($end > $total_items)
|
if($end > $total_items)
|
||||||
{
|
{
|
||||||
$end = $total_items;
|
$end = $total_items;
|
||||||
|
@ -653,18 +691,19 @@ class Old_Tainacan extends Importer
|
||||||
* get values for a single item
|
* get values for a single item
|
||||||
*
|
*
|
||||||
* @param $index
|
* @param $index
|
||||||
|
* @param $collection_id
|
||||||
* @return array with field_source's as the index and values for the
|
* @return array with field_source's as the index and values for the
|
||||||
* item
|
* item
|
||||||
*
|
*
|
||||||
* Ex: [ 'Field1' => 'value1', 'Field2' => [ 'value2','value3' ]
|
* Ex: [ 'Field1' => 'value1', 'Field2' => [ 'value2','value3' ]
|
||||||
*/
|
*/
|
||||||
public function process_item($index)
|
public function process_item( $index, $collection_id )
|
||||||
{
|
{
|
||||||
$processedItem = [];
|
$processedItem = [];
|
||||||
$headers = $this->get_fields();
|
$headers = $this->get_fields();
|
||||||
|
|
||||||
// search the index in the file and get values
|
// search the index in the file and get values
|
||||||
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
/*$file = new \SplFileObject( $this->tmp_file, 'r' );
|
||||||
$file_content = unserialize($file->fread($file->getSize()));
|
$file_content = unserialize($file->fread($file->getSize()));
|
||||||
$values = $file_content->items[$index];
|
$values = $file_content->items[$index];
|
||||||
foreach ($headers as $header)
|
foreach ($headers as $header)
|
||||||
|
@ -687,7 +726,7 @@ class Old_Tainacan extends Importer
|
||||||
$processedItem[$header] = $values->item->{$header};
|
$processedItem[$header] = $values->item->{$header};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return $processedItem;
|
return $processedItem;
|
||||||
}
|
}
|
||||||
|
@ -733,7 +772,7 @@ class Old_Tainacan extends Importer
|
||||||
|
|
||||||
$newField->set_field_type('Tainacan\Field_Types\\'.$type);
|
$newField->set_field_type('Tainacan\Field_Types\\'.$type);
|
||||||
|
|
||||||
$newField->set_collection($this->collection);
|
$newField->set_collection($this->actual_collection);
|
||||||
$newField->validate(); // there is no user input here, so we can be sure it will validate.
|
$newField->validate(); // there is no user input here, so we can be sure it will validate.
|
||||||
|
|
||||||
$newField = $fields_repository->insert($newField);
|
$newField = $fields_repository->insert($newField);
|
||||||
|
@ -759,19 +798,29 @@ class Old_Tainacan extends Importer
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method implemented by the child importer class to return the number of items to be imported
|
* Method implemented by the child importer class to return the number of items to be imported
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function get_total_items_from_source()
|
public function get_total_items_from_source( $collection_id ) {
|
||||||
{
|
$info = wp_remote_get( $this->get_url() . $this->tainacan_api_address . "/collections/".$collection_id."/items" );
|
||||||
if(!isset($this->tmp_file)){
|
$info = json_decode($info['body']);
|
||||||
return 0;
|
return $this->total_items = $info->found_items;
|
||||||
}
|
|
||||||
|
|
||||||
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
|
||||||
$file_content = unserialize($file->fread($file->getSize()));
|
|
||||||
|
|
||||||
return $this->total_items = $file_content->found_items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method implemented by the child importer class to return the number of items to be imported
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function get_progress_total_from_source(){
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method implemented by the child importer class to return the number of items to be imported
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function get_source_fields(){
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Importer
|
||||||
|
*
|
||||||
|
* Example Importer class
|
||||||
|
*
|
||||||
|
* used to learn how to write an importer and to
|
||||||
|
* create test collections and items
|
||||||
|
*
|
||||||
|
* Example how to invoke it
|
||||||
|
*
|
||||||
|
* add_action('init', function() {
|
||||||
|
* if ( isset($_GET['run_test_importer']) && $_GET['run_test_importer'] == 'go' ) {
|
||||||
|
* global $Tainacan_Importer_Handler;
|
||||||
|
* $test = new \Tainacan\Importer\Test_Importer();
|
||||||
|
* $Tainacan_Importer_Handler->add_to_queue($test);
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* Put this code somewhere and access any URL of your site with ?run_test_importer=go
|
||||||
|
*
|
||||||
|
* TODO: check validate() methods and write log & abort importer in case of error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Tainacan\Importer;
|
||||||
|
use \Tainacan\Entities;
|
||||||
|
|
||||||
|
class Test_Importer extends Importer {
|
||||||
|
|
||||||
|
protected $manual_mapping = false;
|
||||||
|
protected $manual_collection = false;
|
||||||
|
|
||||||
|
protected $steps = [
|
||||||
|
|
||||||
|
[
|
||||||
|
'name' => 'Create Taxonomies',
|
||||||
|
'callback' => 'create_taxonomies'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Create Collections',
|
||||||
|
'callback' => 'create_collections'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Import Items',
|
||||||
|
'callback' => 'process_collections'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Post-configure taxonomies',
|
||||||
|
'callback' => 'close_taxonomies'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Finalize',
|
||||||
|
'callback' => 'finish_processing'
|
||||||
|
]
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct($attributes = array()) {
|
||||||
|
parent::__construct($attributes);
|
||||||
|
|
||||||
|
$this->tax_repo = \Tainacan\Repositories\Taxonomies::get_instance();
|
||||||
|
$this->col_repo = \Tainacan\Repositories\Collections::get_instance();
|
||||||
|
$this->items_repo = \Tainacan\Repositories\Items::get_instance();
|
||||||
|
$this->fields_repo = \Tainacan\Repositories\Fields::get_instance();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create_taxonomies() {
|
||||||
|
|
||||||
|
$tax1 = new Entities\Taxonomy();
|
||||||
|
$tax1->set_name('Color');
|
||||||
|
$tax1->set_allow_insert('yes');
|
||||||
|
$tax1->set_status('publish');
|
||||||
|
$tax1->validate();
|
||||||
|
$tax1 = $this->tax_repo->insert($tax1);
|
||||||
|
|
||||||
|
$this->add_transient('tax_1_id', $tax1->get_id());
|
||||||
|
|
||||||
|
$tax2 = new Entities\Taxonomy();
|
||||||
|
$tax2->set_name('Quality');
|
||||||
|
$tax2->set_allow_insert('yes');
|
||||||
|
$tax2->set_status('publish');
|
||||||
|
$tax2->validate();
|
||||||
|
$tax2 = $this->tax_repo->insert($tax2);
|
||||||
|
|
||||||
|
$this->add_transient('tax_2_id', $tax2->get_id());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create_collections() {
|
||||||
|
|
||||||
|
$col1 = new Entities\Collection();
|
||||||
|
$col1->set_name('Collection 1');
|
||||||
|
$col1->set_status('publish');
|
||||||
|
$col1->validate();
|
||||||
|
$col1 = $this->col_repo->insert($col1);
|
||||||
|
|
||||||
|
$col2 = new Entities\Collection();
|
||||||
|
$col2->set_name('Collection 2');
|
||||||
|
$col2->set_status('publish');
|
||||||
|
$col2->validate();
|
||||||
|
$col2 = $this->col_repo->insert($col2);
|
||||||
|
|
||||||
|
$col1_map = [];
|
||||||
|
$col2_map = [];
|
||||||
|
|
||||||
|
// fields
|
||||||
|
|
||||||
|
// core fields
|
||||||
|
$col1_core_title = $col1->get_core_title_field();
|
||||||
|
$col1_core_description = $col1->get_core_description_field();
|
||||||
|
$col1_map[$col1_core_title->get_id()] = 'field1';
|
||||||
|
$col1_map[$col1_core_description->get_id()] = 'field2';
|
||||||
|
|
||||||
|
$field = new Entities\Field();
|
||||||
|
$field->set_name('Color');
|
||||||
|
$field->set_collection($col1);
|
||||||
|
$field->set_field_type('Tainacan\Field_Types\Category');
|
||||||
|
$field->set_field_type_options([
|
||||||
|
'taxonomy_id' => $this->get_transient('tax_1_id'),
|
||||||
|
'allow_new_terms' => true
|
||||||
|
]);
|
||||||
|
$field->set_status('publish');
|
||||||
|
$field->validate();
|
||||||
|
$field = $this->fields_repo->insert($field);
|
||||||
|
$col1_map[$field->get_id()] = 'field3';
|
||||||
|
$this->add_transient('tax_1_field', $field->get_id());
|
||||||
|
|
||||||
|
|
||||||
|
$field = new Entities\Field();
|
||||||
|
$field->set_name('Quality');
|
||||||
|
$field->set_collection($col1);
|
||||||
|
$field->set_field_type('Tainacan\Field_Types\Category');
|
||||||
|
$field->set_field_type_options([
|
||||||
|
'taxonomy_id' => $this->get_transient('tax_2_id'),
|
||||||
|
'allow_new_terms' => true
|
||||||
|
]);
|
||||||
|
$field->set_status('publish');
|
||||||
|
$field->validate();
|
||||||
|
$field = $this->fields_repo->insert($field);
|
||||||
|
$col1_map[$field->get_id()] = 'field4';
|
||||||
|
$this->add_transient('tax_2_field', $field->get_id());
|
||||||
|
|
||||||
|
$this->add_collection([
|
||||||
|
'id' => $col1->get_id(),
|
||||||
|
'map' => $col1_map,
|
||||||
|
'total_items' => $this->get_col1_number_of_items(),
|
||||||
|
'source_id' => 'col1'
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Collection 2
|
||||||
|
// core fields
|
||||||
|
$col2_core_title = $col2->get_core_title_field();
|
||||||
|
$col2_core_description = $col2->get_core_description_field();
|
||||||
|
$col2_map[$col2_core_title->get_id()] = 'field1';
|
||||||
|
$col2_map[$col2_core_description->get_id()] = 'field2';
|
||||||
|
|
||||||
|
$field = new Entities\Field();
|
||||||
|
$field->set_name('Test Field');
|
||||||
|
$field->set_collection($col2);
|
||||||
|
$field->set_field_type('Tainacan\Field_Types\Text');
|
||||||
|
$field->set_status('publish');
|
||||||
|
$field->validate();
|
||||||
|
$field = $this->fields_repo->insert($field);
|
||||||
|
$col2_map[$field->get_id()] = 'field3';
|
||||||
|
|
||||||
|
$this->add_collection([
|
||||||
|
'id' => $col2->get_id(),
|
||||||
|
'map' => $col2_map,
|
||||||
|
'total_items' => $this->get_col2_number_of_items(),
|
||||||
|
'source_id' => 'col2'
|
||||||
|
]);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function close_taxonomies() {
|
||||||
|
|
||||||
|
$tax1 = $this->tax_repo->fetch( $this->get_transient('tax_1_id') );
|
||||||
|
$tax1->set_allow_insert('no');
|
||||||
|
$tax1->validate();
|
||||||
|
$tax1 = $this->tax_repo->insert($tax1);
|
||||||
|
|
||||||
|
$tax2 = $this->tax_repo->fetch( $this->get_transient('tax_2_id') );
|
||||||
|
$tax2->set_allow_insert('no');
|
||||||
|
$tax2->validate();
|
||||||
|
$tax2 = $this->tax_repo->insert($tax2);
|
||||||
|
|
||||||
|
|
||||||
|
$field1 = $this->fields_repo->fetch( $this->get_transient('tax_1_field') );
|
||||||
|
$options = $field1->get_field_type_options();
|
||||||
|
$options['allow_new_terms'] = false;
|
||||||
|
$field1->set_field_type_options($options);
|
||||||
|
$field1->validate();
|
||||||
|
$this->fields_repo->insert($field1);
|
||||||
|
|
||||||
|
$field2 = $this->fields_repo->fetch( $this->get_transient('tax_2_field') );
|
||||||
|
$options = $field2->get_field_type_options();
|
||||||
|
$options['allow_new_terms'] = false;
|
||||||
|
$field2->set_field_type_options($options);
|
||||||
|
$field2->validate();
|
||||||
|
$this->fields_repo->insert($field2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function finish_processing() {
|
||||||
|
|
||||||
|
// Lets just pretend we are doing something really important
|
||||||
|
$important_stuff = 5;
|
||||||
|
$current = $this->get_in_step_count();
|
||||||
|
if ($current <= $important_stuff) {
|
||||||
|
// This is very important
|
||||||
|
sleep(5);
|
||||||
|
$current ++;
|
||||||
|
return $current;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process_item($index, $collection_definition) {
|
||||||
|
|
||||||
|
$method = 'get_' . $collection_definition['source_id'] . '_item';
|
||||||
|
$item = $this->$method($index);
|
||||||
|
return $item;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dummy methods
|
||||||
|
*
|
||||||
|
* This could be reading from a file, or making requests to an API
|
||||||
|
*
|
||||||
|
* Here we are just returning random values
|
||||||
|
*/
|
||||||
|
public function get_col1_number_of_items() {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
public function get_col2_number_of_items() {
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
public function get_col1_item($index) {
|
||||||
|
|
||||||
|
$terms1 = [
|
||||||
|
'orange', 'red', 'purple', 'blue', 'black', 'yellow'
|
||||||
|
];
|
||||||
|
$terms2 = [
|
||||||
|
'good', 'awesome', 'disgusting', 'bad', 'horrible', 'regular'
|
||||||
|
];
|
||||||
|
|
||||||
|
return [
|
||||||
|
'field1' => 'Title ' . $index,
|
||||||
|
'field2' => 'Description ' . $index,
|
||||||
|
'field3' => $terms1[array_rand($terms1)],
|
||||||
|
'field4' => $terms2[array_rand($terms2)],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
public function get_col2_item($index) {
|
||||||
|
return [
|
||||||
|
'field1' => 'Collection 2 item ' . $index,
|
||||||
|
'field2' => 'Collection 2 item description ' . $index,
|
||||||
|
'field3' => 'Collection 2 whatever ' . $index,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class ScriptTainacanOld {
|
||||||
|
|
||||||
|
var $step = 0;
|
||||||
|
var $url = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* start the execution
|
||||||
|
*/
|
||||||
|
function __construct($argv) {
|
||||||
|
|
||||||
|
$this->parse_args($argv);
|
||||||
|
$this->run();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse args from and set the attributs
|
||||||
|
* 1 - Old Tainacan url (required)
|
||||||
|
*/
|
||||||
|
function parse_args($argv) {
|
||||||
|
|
||||||
|
if (!is_array($argv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
if (isset($argv[1])) {
|
||||||
|
|
||||||
|
if (filter_var($argv[1], FILTER_VALIDATE_URL)) {
|
||||||
|
$this->url = $argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($argv[2])) {
|
||||||
|
|
||||||
|
if (is_numeric($argv[2])) {
|
||||||
|
$this->step = $argv[2];
|
||||||
|
} else {
|
||||||
|
$this->run = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* echo message in prompt line
|
||||||
|
*/
|
||||||
|
function log($msg) {
|
||||||
|
|
||||||
|
echo $msg . PHP_EOL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
|
||||||
|
$start = $partial = microtime(true);
|
||||||
|
|
||||||
|
// Avoid warnings
|
||||||
|
$_SERVER['SERVER_PROTOCOL'] = "HTTP/1.1";
|
||||||
|
$_SERVER['REQUEST_METHOD'] = "GET";
|
||||||
|
|
||||||
|
define( 'WP_USE_THEMES', false );
|
||||||
|
define( 'SHORTINIT', false );
|
||||||
|
require( dirname(__FILE__) . '/../../../../wp-blog-header.php' );
|
||||||
|
|
||||||
|
$old_tainacan = new \Tainacan\Importer\Old_Tainacan();
|
||||||
|
$id = $old_tainacan->get_id();
|
||||||
|
|
||||||
|
$_SESSION['tainacan_importer'][$id]->set_url($url);
|
||||||
|
$_SESSION['tainacan_importer'][$id]->set_repository();
|
||||||
|
|
||||||
|
while (!$_SESSION['tainacan_importer'][$id]->is_finished()){
|
||||||
|
$_SESSION['tainacan_importer'][$id]->run();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scripttime = microtime(true) - $start;
|
||||||
|
|
||||||
|
$this->log("==========================================================");
|
||||||
|
$this->log("==========================================================");
|
||||||
|
$this->log("=== Fim do script. Tempo de execução {$scripttime}s");
|
||||||
|
$this->log("==========================================================");
|
||||||
|
$this->log("==========================================================");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = new ScriptTainacanOld($argv);
|
|
@ -122,9 +122,9 @@ export default {
|
||||||
loadItems(to) {
|
loadItems(to) {
|
||||||
|
|
||||||
// Forces fetch_only to be filled before any search happens
|
// Forces fetch_only to be filled before any search happens
|
||||||
if (this.$store.getters['search/getFetchOnly'] == undefined)
|
if (this.$store.getters['search/getFetchOnly'] == undefined) {
|
||||||
this.$emit( 'hasToPrepareFieldsAndFilters', to);
|
this.$emit( 'hasToPrepareFieldsAndFilters', to);
|
||||||
else {
|
} else {
|
||||||
this.$emit( 'isLoadingItems', true);
|
this.$emit( 'isLoadingItems', true);
|
||||||
this.$store.dispatch('collection/fetchItems',
|
this.$store.dispatch('collection/fetchItems',
|
||||||
{ 'collectionId': this.collectionId,
|
{ 'collectionId': this.collectionId,
|
||||||
|
|
|
@ -171,7 +171,7 @@ export const updateTerm = ({ commit }, { categoryId, termId, name, description,
|
||||||
|
|
||||||
export const fetchTerms = ({ commit }, categoryId ) => {
|
export const fetchTerms = ({ commit }, categoryId ) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axios.tainacan.get(`/taxonomy/${categoryId}/terms/?hideempty=0`)
|
axios.tainacan.get(`/taxonomy/${categoryId}/terms/?hideempty=0&order=asc`)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
let terms = res.data;
|
let terms = res.data;
|
||||||
commit('setTerms', terms);
|
commit('setTerms', terms);
|
||||||
|
|
|
@ -13,6 +13,13 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, is
|
||||||
if (postQueries.metaquery != undefined && postQueries.metaquery.length > 0)
|
if (postQueries.metaquery != undefined && postQueries.metaquery.length > 0)
|
||||||
hasFiltered = true;
|
hasFiltered = true;
|
||||||
|
|
||||||
|
// Garanttees at least empty fetch_only are passed in case none is found
|
||||||
|
if (qs.stringify(postQueries.fetch_only) == '')
|
||||||
|
dispatch('search/add_fetchonly', {} , { root: true });
|
||||||
|
|
||||||
|
if (qs.stringify(postQueries.fetch_only['meta']) == '')
|
||||||
|
dispatch('search/add_fetchonly_meta', 0 , { root: true });
|
||||||
|
|
||||||
// Differentiates between repository level and collection level queries
|
// Differentiates between repository level and collection level queries
|
||||||
let endpoint = '/collection/'+collectionId+'/items?'
|
let endpoint = '/collection/'+collectionId+'/items?'
|
||||||
|
|
||||||
|
@ -22,26 +29,23 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, is
|
||||||
if (!isOnTheme)
|
if (!isOnTheme)
|
||||||
endpoint = endpoint + 'context=edit&'
|
endpoint = endpoint + 'context=edit&'
|
||||||
|
|
||||||
if (qs.stringify(postQueries.fetch_only['meta']) != '') {
|
axios.tainacan.get(endpoint + qs.stringify(postQueries))
|
||||||
axios.tainacan.get(endpoint + qs.stringify(postQueries))
|
.then(res => {
|
||||||
.then(res => {
|
|
||||||
|
let items = res.data;
|
||||||
let items = res.data;
|
let viewModeObject = tainacan_plugin.registered_view_modes[postQueries.view_mode];
|
||||||
let viewModeObject = tainacan_plugin.registered_view_modes[postQueries.view_mode];
|
|
||||||
|
if (isOnTheme && viewModeObject != undefined && viewModeObject.type == 'template') {
|
||||||
if (isOnTheme && viewModeObject != undefined && viewModeObject.type == 'template') {
|
commit('setItemsListTemplate', items );
|
||||||
commit('setItemsListTemplate', items );
|
resolve({'itemsListTemplate': items, 'total': res.headers['x-wp-total'], hasFiltered: hasFiltered});
|
||||||
resolve({'itemsListTemplate': items, 'total': res.headers['x-wp-total'], hasFiltered: hasFiltered});
|
} else {
|
||||||
} else {
|
commit('setItems', items );
|
||||||
commit('setItems', items );
|
resolve({'items': items, 'total': res.headers['x-wp-total'], hasFiltered: hasFiltered});
|
||||||
resolve({'items': items, 'total': res.headers['x-wp-total'], hasFiltered: hasFiltered});
|
}
|
||||||
}
|
dispatch('search/setTotalItems', res.headers['x-wp-total'], { root: true } );
|
||||||
dispatch('search/setTotalItems', res.headers['x-wp-total'], { root: true } );
|
})
|
||||||
})
|
.catch(error => reject(error));
|
||||||
.catch(error => reject(error));
|
|
||||||
} else {
|
|
||||||
reject("No fecth_only meta was found.");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -179,15 +183,16 @@ export const updateCollection = ({ commit }, {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendCollection = ( { commit }, { name, description, status }) => {
|
export const sendCollection = ( { commit }, { name, description, status, mapper }) => {
|
||||||
return new Promise(( resolve, reject ) => {
|
return new Promise(( resolve, reject ) => {
|
||||||
axios.tainacan.post('/collections/', {
|
axios.tainacan.post('/collections/', {
|
||||||
name: name,
|
name: name,
|
||||||
description: description,
|
description: description,
|
||||||
status: status
|
status: status,
|
||||||
|
'exposer-map': mapper
|
||||||
})
|
})
|
||||||
.then( res => {
|
.then( res => {
|
||||||
commit('setCollection', { name: name, description: description, status: status });
|
commit('setCollection', { name: name, description: description, status: status, mapper: mapper });
|
||||||
resolve( res.data );
|
resolve( res.data );
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
|
|
@ -126,7 +126,25 @@ export const fetchFieldTypes = ({commit}) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const updateFieldTypes = ({commit}, fieldTypes) => {
|
export const updateFieldTypes = ({commit}, fieldTypes) => {
|
||||||
commit('setFieldTypes', fieldTypes);
|
commit('setFieldTypes', fieldTypes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const fetchFieldMappers = ({commit}) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.tainacan.get('/field-mappers')
|
||||||
|
.then((res) => {
|
||||||
|
let fieldMappers = res.data;
|
||||||
|
commit('setFieldMappers', fieldMappers);
|
||||||
|
resolve(fieldMappers);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateFieldMappers = ({commit}, fieldMappers) => {
|
||||||
|
commit('setFieldMappers', fieldMappers);
|
||||||
|
};
|
||||||
|
|
|
@ -5,4 +5,8 @@ export const getFields = state => {
|
||||||
|
|
||||||
export const getFieldTypes = state => {
|
export const getFieldTypes = state => {
|
||||||
return state.fieldTypes;
|
return state.fieldTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getFieldMappers = state => {
|
||||||
|
return state.fieldMappers;
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ import * as mutations from './mutations';
|
||||||
const state = {
|
const state = {
|
||||||
fields: [],
|
fields: [],
|
||||||
fieldTypes: [],
|
fieldTypes: [],
|
||||||
|
fieldMappers: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -18,3 +18,7 @@ export const setFields = (state, fields) => {
|
||||||
export const setFieldTypes = (state, fieldTypes) => {
|
export const setFieldTypes = (state, fieldTypes) => {
|
||||||
state.fieldTypes = fieldTypes;
|
state.fieldTypes = fieldTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const setFieldMappers = (state, fieldMappers) => {
|
||||||
|
state.fieldMappers = fieldMappers;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function tainacan_create_bd_process_db() {
|
||||||
|
global $wpdb;
|
||||||
|
$table_name = $wpdb->prefix . 'tnc_bg_process';
|
||||||
|
$charset_collate = $wpdb->get_charset_collate();
|
||||||
|
$max_index_length = 191;
|
||||||
|
|
||||||
|
$query = "CREATE TABLE IF NOT EXISTS $table_name (
|
||||||
|
ID bigint(20) unsigned NOT NULL auto_increment,
|
||||||
|
user_id bigint(20) unsigned NOT NULL default '0',
|
||||||
|
priority bigint(20) unsigned NOT NULL default 10,
|
||||||
|
queued_on datetime NOT NULL default '0000-00-00 00:00:00',
|
||||||
|
processed_last datetime NOT NULL default '0000-00-00 00:00:00',
|
||||||
|
data longtext NOT NULL,
|
||||||
|
action text NOT NULL,
|
||||||
|
done boolean not null default 0,
|
||||||
|
PRIMARY KEY (ID),
|
||||||
|
KEY user_id (user_id),
|
||||||
|
KEY action (action($max_index_length))
|
||||||
|
) $charset_collate;\n";
|
||||||
|
|
||||||
|
$wpdb->query($query);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -16,13 +16,15 @@ const TAINACAN_API_DIR = __DIR__ . '/api/';
|
||||||
const TAINACAN_CLASSES_DIR = __DIR__ . '/classes/';
|
const TAINACAN_CLASSES_DIR = __DIR__ . '/classes/';
|
||||||
require_once(TAINACAN_CLASSES_DIR . 'tainacan-creator.php');
|
require_once(TAINACAN_CLASSES_DIR . 'tainacan-creator.php');
|
||||||
require_once(TAINACAN_API_DIR . 'tainacan-rest-creator.php');
|
require_once(TAINACAN_API_DIR . 'tainacan-rest-creator.php');
|
||||||
|
require_once('setup-db.php');
|
||||||
|
|
||||||
// DEV Interface, used for debugging
|
// DEV Interface, used for debugging
|
||||||
require_once('dev-interface/class-tainacan-dev-interface.php');
|
|
||||||
function tnc_enable_dev_wp_interface() {
|
function tnc_enable_dev_wp_interface() {
|
||||||
return defined('TNC_ENABLE_DEV_WP_INTERFACE') && true === TNC_ENABLE_DEV_WP_INTERFACE ? true : false;
|
return defined('TNC_ENABLE_DEV_WP_INTERFACE') && true === TNC_ENABLE_DEV_WP_INTERFACE ? true : false;
|
||||||
}
|
}
|
||||||
if ( tnc_enable_dev_wp_interface() ) {
|
if ( tnc_enable_dev_wp_interface() ) {
|
||||||
|
require_once('dev-interface/class-tainacan-dev-interface.php');
|
||||||
|
require_once('dev-interface/class-tainacan-helpers-html.php');
|
||||||
$Tainacan_Dev_interface = \Tainacan\DevInterface\DevInterface::get_instance();
|
$Tainacan_Dev_interface = \Tainacan\DevInterface\DevInterface::get_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,3 +36,4 @@ add_action( 'plugins_loaded', 'tainacan_load_plugin_textdomain' );
|
||||||
|
|
||||||
$Tainacan_Capabilities = \Tainacan\Capabilities::get_instance();
|
$Tainacan_Capabilities = \Tainacan\Capabilities::get_instance();
|
||||||
register_activation_hook( __FILE__, array( $Tainacan_Capabilities, 'init' ) );
|
register_activation_hook( __FILE__, array( $Tainacan_Capabilities, 'init' ) );
|
||||||
|
register_activation_hook( __FILE__, 'tainacan_create_bd_process_db' );
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'tests_dir' => '/tmp/wordpress-tests-lib',
|
'tests_dir' => '/tmp/wordpress/wordpress-tests-lib',
|
||||||
];
|
];
|
||||||
|
|
||||||
?>
|
|
||||||
|
?>
|
||||||
|
|
|
@ -57,7 +57,8 @@ class Entity_Factory {
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->entity = new $this->entity_type();
|
$this->entity = new $this->entity_type();
|
||||||
$this->repository = $this->repository_type::get_instance();
|
$repo = $this->repository_type;
|
||||||
|
$this->repository = $repo::get_instance();
|
||||||
|
|
||||||
if($publish) {
|
if($publish) {
|
||||||
$this->entity->set_status('publish');
|
$this->entity->set_status('publish');
|
||||||
|
|
|
@ -57,15 +57,15 @@ class TAINACAN_REST_Export_Controller extends TAINACAN_UnitApiTestCase {
|
||||||
$item_metadata = $Tainacan_Item_Metadata->insert($item_metadata);
|
$item_metadata = $Tainacan_Item_Metadata->insert($item_metadata);
|
||||||
|
|
||||||
$item2 = $this->tainacan_entity_factory->create_entity(
|
$item2 = $this->tainacan_entity_factory->create_entity(
|
||||||
'item',
|
'item',
|
||||||
array(
|
array(
|
||||||
'title' => 'item_teste_Export2',
|
'title' => 'item_teste_Export2',
|
||||||
'description' => 'adasdasdsa2',
|
'description' => 'adasdasdsa2',
|
||||||
'collection' => $collection
|
'collection' => $collection
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
$item_metadata2 = new \Tainacan\Entities\Item_Metadata_Entity($item2, $field);
|
$item_metadata2 = new \Tainacan\Entities\Item_Metadata_Entity($item2, $field);
|
||||||
|
|
||||||
|
@ -76,15 +76,15 @@ class TAINACAN_REST_Export_Controller extends TAINACAN_UnitApiTestCase {
|
||||||
$item_metadata2 = $Tainacan_Item_Metadata->insert($item_metadata2);
|
$item_metadata2 = $Tainacan_Item_Metadata->insert($item_metadata2);
|
||||||
|
|
||||||
$item3 = $this->tainacan_entity_factory->create_entity(
|
$item3 = $this->tainacan_entity_factory->create_entity(
|
||||||
'item',
|
'item',
|
||||||
array(
|
array(
|
||||||
'title' => 'item_teste_Export3',
|
'title' => 'item_teste_Export3',
|
||||||
'description' => 'adasdasdsa3',
|
'description' => 'adasdasdsa3',
|
||||||
'collection' => $collection
|
'collection' => $collection
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
$item_metadata3 = new \Tainacan\Entities\Item_Metadata_Entity($item3, $field);
|
$item_metadata3 = new \Tainacan\Entities\Item_Metadata_Entity($item3, $field);
|
||||||
|
|
||||||
|
@ -103,15 +103,35 @@ class TAINACAN_REST_Export_Controller extends TAINACAN_UnitApiTestCase {
|
||||||
$item_exposer_json = json_encode([
|
$item_exposer_json = json_encode([
|
||||||
'exposer-type' => 'Xml',
|
'exposer-type' => 'Xml',
|
||||||
'exposer-map' => 'Value',
|
'exposer-map' => 'Value',
|
||||||
|
'export-background' => false
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$query = [
|
||||||
|
'orderby' => 'id',
|
||||||
|
'order' => 'asc',
|
||||||
|
];
|
||||||
|
|
||||||
$request = new \WP_REST_Request('GET', $this->namespace . '/export/collection/' . $collection->get_id() );
|
$request = new \WP_REST_Request('GET', $this->namespace . '/export/collection/' . $collection->get_id() );
|
||||||
|
$request->set_query_params($query);
|
||||||
$request->set_body($item_exposer_json);
|
$request->set_body($item_exposer_json);
|
||||||
$response = $this->server->dispatch($request);
|
$response = $this->server->dispatch($request);
|
||||||
$this->assertEquals(200, $response->get_status());
|
$this->assertEquals(200, $response->get_status());
|
||||||
$data = $response->get_data();
|
$data = $response->get_data();
|
||||||
print_r($data);
|
|
||||||
|
$this->assertInstanceOf('SimpleXMLElement', $xml = @simplexml_load_string($data));
|
||||||
|
|
||||||
|
$this->assertEquals(3, $xml->count());
|
||||||
|
$i = 0;
|
||||||
|
foreach ($xml->children() as $xml_item ) {
|
||||||
|
$fields = $items[$i]->get_fields();
|
||||||
|
foreach ($fields as $field_meta) {
|
||||||
|
$field = $field_meta->get_field();
|
||||||
|
$this->assertEquals($field_meta->get_value(), $xml_item->{$field->get_name()});
|
||||||
|
//echo "{$field->get_name()}:{$field_meta->get_value()}"; // uncomment if need debug
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -166,6 +166,58 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group exposers-slug
|
||||||
|
*/
|
||||||
|
public function test_exposer_map_by_slug() {
|
||||||
|
global $Tainacan_Fields, $Tainacan_Item_Metadata;
|
||||||
|
extract($this->create_meta_requirements());
|
||||||
|
|
||||||
|
$item__metadata_json = json_encode([
|
||||||
|
'values' => 'TestValues_exposers_slug',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$request = new \WP_REST_Request('POST', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/' . $this->field->get_id() );
|
||||||
|
$request->set_body($item__metadata_json);
|
||||||
|
|
||||||
|
$response = $this->server->dispatch($request);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response->get_status());
|
||||||
|
|
||||||
|
$data = $response->get_data();
|
||||||
|
|
||||||
|
$this->assertEquals($this->item->get_id(), $data['item']['id']);
|
||||||
|
$this->assertEquals('TestValues_exposers_slug', $data['value']);
|
||||||
|
|
||||||
|
$item_exposer_json = json_encode([
|
||||||
|
'exposer-map' => 'dublin-core',
|
||||||
|
]);
|
||||||
|
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/'. $this->field->get_id() );
|
||||||
|
$request->set_body($item_exposer_json);
|
||||||
|
$response = $this->server->dispatch($request);
|
||||||
|
$this->assertEquals(200, $response->get_status());
|
||||||
|
$data = $response->get_data();
|
||||||
|
$this->assertEquals('TestValues_exposers_slug', $data['dc:language']);
|
||||||
|
|
||||||
|
$item_exposer_json = json_encode([
|
||||||
|
'exposer-type' => 'xml',
|
||||||
|
'exposer-map' => 'dublin-core',
|
||||||
|
]);
|
||||||
|
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
|
||||||
|
$request->set_body($item_exposer_json);
|
||||||
|
$response = $this->server->dispatch($request);
|
||||||
|
$this->assertEquals(200, $response->get_status());
|
||||||
|
$data = $response->get_data();
|
||||||
|
|
||||||
|
$xml = new \SimpleXMLElement($data);
|
||||||
|
$rdf = $xml->children(\Tainacan\Exposers\Mappers\Dublin_Core::XML_RDF_NAMESPACE);
|
||||||
|
$dc = $rdf->children(\Tainacan\Exposers\Mappers\Dublin_Core::XML_DC_NAMESPACE);
|
||||||
|
|
||||||
|
$this->assertEquals('adasdasdsa', $dc->description);
|
||||||
|
$this->assertEquals('item_teste_Expose', $dc->title);
|
||||||
|
$this->assertEquals('TestValues_exposers_slug', $dc->language);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group oai-pmh
|
* @group oai-pmh
|
||||||
*/
|
*/
|
||||||
|
@ -345,6 +397,42 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
|
||||||
$this->assertEquals('TestValues_exposers', $data['teste_Expose']);
|
$this->assertEquals('TestValues_exposers', $data['teste_Expose']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group mapped_new_collection
|
||||||
|
*/
|
||||||
|
public function test_mapped_new_collection() {
|
||||||
|
$collection_JSON = json_encode([
|
||||||
|
'exposer-map' => 'Dublin Core',
|
||||||
|
'name' => 'TesteJsonAddDublin_Core',
|
||||||
|
'description' => 'Teste JSON Dublin Core mapped',
|
||||||
|
'status' => 'publish'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$mapper = new \Tainacan\Exposers\Mappers\Dublin_Core();
|
||||||
|
|
||||||
|
$request = new \WP_REST_Request('POST', $this->namespace . '/collections');
|
||||||
|
$request->set_body($collection_JSON);
|
||||||
|
$response = $this->server->dispatch($request);
|
||||||
|
$this->assertEquals(201, $response->get_status(), sprintf('response: %s', print_r($response, true)));
|
||||||
|
$collection_array = $response->get_data();
|
||||||
|
$id = $collection_array['id'];
|
||||||
|
$Tainacan_collections = \Tainacan\Repositories\Collections::get_instance();
|
||||||
|
$collection = $Tainacan_collections->fetch($id);
|
||||||
|
|
||||||
|
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
||||||
|
$fields = $Tainacan_Fields->fetch_by_collection( $collection, [ 'order' => 'id' ], 'OBJECT' );
|
||||||
|
|
||||||
|
$this->assertEquals(count($mapper->metadata), count($fields));
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$this->assertTrue(array_key_exists($field->get_slug(), $mapper->metadata));
|
||||||
|
if(! array_key_exists('core_field', $mapper->metadata[$field->get_slug()]) || $mapper->metadata[$field->get_slug()]['core_field'] == false) {
|
||||||
|
$this->assertEquals($mapper->metadata[$field->get_slug()]['URI'], $field->get_description());
|
||||||
|
}
|
||||||
|
$this->assertEquals($mapper->metadata[$field->get_slug()]['label'], $field->get_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tainacan\Tests;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group api
|
||||||
|
*/
|
||||||
|
class TAINACAN_REST_Field_Mappers_Controller extends TAINACAN_UnitApiTestCase {
|
||||||
|
|
||||||
|
public function test_get_field_mappers(){
|
||||||
|
|
||||||
|
$field_mapper_request = new \WP_REST_Request('GET', $this->namespace . '/field-mappers');
|
||||||
|
|
||||||
|
$field_mapper_response = $this->server->dispatch($field_mapper_request);
|
||||||
|
|
||||||
|
$data = $field_mapper_response->get_data();
|
||||||
|
|
||||||
|
$Tainacan_Fields = \Tainacan\Exposers\Exposers::get_instance();
|
||||||
|
|
||||||
|
$field_mappers = $Tainacan_Fields->get_mappers("OBJECT");
|
||||||
|
|
||||||
|
$this->assertEquals(count($field_mappers), count($data));
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($data); $i++) {
|
||||||
|
$this->assertEquals($field_mappers[$i]->slug, $data[$i]['slug']);
|
||||||
|
$this->assertEquals($field_mappers[$i]->name, $data[$i]['name']);
|
||||||
|
$this->assertEquals($field_mappers[$i]->allow_extra_fields, $data[$i]['allow_extra_fields']);
|
||||||
|
$this->assertEquals($field_mappers[$i]->context_url, $data[$i]['context_url']);
|
||||||
|
$this->assertEquals($field_mappers[$i]->metadata, $data[$i]['metadata']);
|
||||||
|
$this->assertEquals($field_mappers[$i]->prefix, $data[$i]['prefix']);
|
||||||
|
$this->assertEquals($field_mappers[$i]->sufix, $data[$i]['sufix']);
|
||||||
|
$this->assertEquals($field_mappers[$i]->header, $data[$i]['header']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -49,10 +49,80 @@ class DefaultCapabilities extends TAINACAN_UnitTestCase {
|
||||||
$this->assertTrue(current_user_can($entity_cap->$cap), "tainacan-$role_name does not have capability {$entity_cap->$cap}");
|
$this->assertTrue(current_user_can($entity_cap->$cap), "tainacan-$role_name does not have capability {$entity_cap->$cap}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group capabilities_denpendecies
|
||||||
|
*/
|
||||||
|
function test_capabilities_denpendecies() {
|
||||||
|
|
||||||
|
$collection = $this->tainacan_entity_factory->create_entity(
|
||||||
|
'collection',
|
||||||
|
array(
|
||||||
|
'name' => 'test capabilities denpendecies',
|
||||||
|
),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
$item = $this->tainacan_entity_factory->create_entity(
|
||||||
|
'item',
|
||||||
|
array(
|
||||||
|
'title' => 'test capabilities denpendecies Item',
|
||||||
|
'collection' => $collection,
|
||||||
|
),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
$Tainacan_Capabilities = \Tainacan\Capabilities::get_instance();
|
||||||
|
$deps = $Tainacan_Capabilities::$dependencies;
|
||||||
|
$defaults_caps = $Tainacan_Capabilities->defaults;
|
||||||
|
$tainacan_roles = $Tainacan_Capabilities->get_tainacan_roles();
|
||||||
|
|
||||||
|
foreach ($defaults_caps as $post_type => $wp_append_roles) {
|
||||||
|
if(array_key_exists($post_type, $deps)) {
|
||||||
|
$entity = false;
|
||||||
|
$entity_cap = false;
|
||||||
|
|
||||||
|
if($post_type != 'tainacan-items') {
|
||||||
|
$entity = Repository::get_entity_by_post_type($post_type);
|
||||||
|
$entity_cap = $entity->get_capabilities();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($wp_append_roles as $role_name => $caps) {
|
||||||
|
$role = get_role($role_name);
|
||||||
|
|
||||||
|
$new_user = $this->factory()->user->create(array( 'role' => $role_name ));
|
||||||
|
wp_set_current_user($new_user);
|
||||||
|
|
||||||
|
foreach ($caps as $cap) {
|
||||||
|
if(array_key_exists($cap, $deps[$post_type])) {
|
||||||
|
$dep_cap = $deps[$post_type][$cap];
|
||||||
|
if($post_type == 'tainacan-items') {
|
||||||
|
$this->assertTrue(current_user_can($dep_cap), "$role_name does not have a dependency capability {$dep_cap} for tainacan-items" );
|
||||||
|
} else {
|
||||||
|
$this->assertTrue(current_user_can($dep_cap), "$role_name does not have a dependency capability {$dep_cap} for {$entity_cap->$cap}" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_user = $this->factory()->user->create(array( 'role' => 'tainacan-' . $role_name ));
|
||||||
|
wp_set_current_user($new_user);
|
||||||
|
|
||||||
|
if(in_array($role_name, $tainacan_roles) ) {
|
||||||
|
foreach ($caps as $cap) {
|
||||||
|
if(array_key_exists($cap, $deps[$post_type])) {
|
||||||
|
$dep_cap = $deps[$post_type][$cap];
|
||||||
|
if($post_type == 'tainacan-items') {
|
||||||
|
$this->assertTrue(current_user_can($dep_cap), "tainaca-$role_name does not have a dependency capability {$dep_cap} for tainacan-items" );
|
||||||
|
} else {
|
||||||
|
$this->assertTrue(current_user_can($dep_cap), "tainaca-$role_name does not have a dependency capability {$dep_cap} for {$entity_cap->$cap}" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ use Tainacan\Importer;
|
||||||
|
|
||||||
class ImporterTests extends TAINACAN_UnitTestCase {
|
class ImporterTests extends TAINACAN_UnitTestCase {
|
||||||
|
|
||||||
public function test_intance_old_tainacan()
|
/*public function test_intance_old_tainacan()
|
||||||
{
|
{
|
||||||
$collection = $this->tainacan_entity_factory->create_entity(
|
$collection = $this->tainacan_entity_factory->create_entity(
|
||||||
'collection',
|
'collection',
|
||||||
|
@ -27,10 +27,10 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
||||||
$old_tainacan_importer = new Importer\Old_Tainacan();
|
$old_tainacan_importer = new Importer\Old_Tainacan();
|
||||||
$id = $old_tainacan_importer->get_id();
|
$id = $old_tainacan_importer->get_id();
|
||||||
$_SESSION['tainacan_importer'][$id]->set_collection( $collection );
|
$_SESSION['tainacan_importer'][$id]->set_collection( $collection );
|
||||||
$this->assertEquals( $collection->get_id(), $_SESSION['tainacan_importer'][$id]->collection->get_id() );
|
this->assertEquals( $collection->get_id(), $_SESSION['tainacan_importer'][$id]->collection->get_id() );
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/*public function test_automapping_old_tainacan()
|
public function test_automapping_old_tainacan()
|
||||||
{
|
{
|
||||||
//$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
|
//$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
|
||||||
//$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
//$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
|
||||||
|
@ -38,25 +38,30 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
||||||
$old_tainacan = new Importer\Old_Tainacan();
|
$old_tainacan = new Importer\Old_Tainacan();
|
||||||
$id = $old_tainacan->get_id();
|
$id = $old_tainacan->get_id();
|
||||||
|
|
||||||
$_SESSION['tainacan_importer'][$id]->set_items_per_step(50);
|
|
||||||
|
|
||||||
//if(!copy('./tests/attachment/json_old_tainacan_base.txt', './tests/attachment/json_old_tainacan.txt'))
|
//if(!copy('./tests/attachment/json_old_tainacan_base.txt', './tests/attachment/json_old_tainacan.txt'))
|
||||||
//{
|
//{
|
||||||
//return false;
|
//return false;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//$_SESSION['tainacan_importer'][$id]->set_file( './tests/attachment/json_old_tainacan.txt' );
|
//$_SESSION['tainacan_importer'][$id]->set_file( './tests/attachment/json_old_tainacan.txt' );
|
||||||
$url = 'http://localhost/wordpress_tainacan/';
|
$url_repository = 'http://localhost/wordpress_tainacan/';
|
||||||
$_SESSION['tainacan_importer'][$id]->set_url($url);
|
$url_repository = '';
|
||||||
$_SESSION['tainacan_importer'][$id]->set_repository();
|
if( $url_repository !== '' ){
|
||||||
|
$_SESSION['tainacan_importer'][$id]->set_url($url_repository);
|
||||||
|
|
||||||
while (!$_SESSION['tainacan_importer'][$id]->is_finished())
|
while (!$_SESSION['tainacan_importer'][$id]->is_finished())
|
||||||
{
|
{
|
||||||
$_SESSION['tainacan_importer'][$id]->run();
|
$_SESSION['tainacan_importer'][$id]->run();
|
||||||
|
}
|
||||||
|
|
||||||
|
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
|
||||||
|
$collections = $Tainacan_Collections->fetch([], 'OBJECT');
|
||||||
|
$this->assertEquals(3, $collections, 'total collection in this url does not match');
|
||||||
|
|
||||||
|
$this->assertTrue(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertTrue(true);
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
/*public function test_file_old_tainacan () {
|
/*public function test_file_old_tainacan () {
|
||||||
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
|
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
|
||||||
|
@ -130,30 +135,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
||||||
|
|
||||||
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_total_items(), count( $items ) );
|
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_total_items(), count( $items ) );
|
||||||
}*/
|
}*/
|
||||||
/**
|
|
||||||
* @group importer
|
|
||||||
*/
|
|
||||||
public function test_instance_csv () {
|
|
||||||
|
|
||||||
$collection = $this->tainacan_entity_factory->create_entity(
|
|
||||||
'collection',
|
|
||||||
array(
|
|
||||||
'name' => 'Other',
|
|
||||||
'description' => 'adasdasdsa',
|
|
||||||
'default_order' => 'DESC',
|
|
||||||
'status' => 'publish'
|
|
||||||
),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
$csv_importer = new Importer\CSV();
|
|
||||||
$id = $csv_importer->get_id();
|
|
||||||
$_SESSION['tainacan_importer'][$id]->set_collection( $collection );
|
|
||||||
|
|
||||||
// here the session is init already
|
|
||||||
$this->assertEquals( $collection->get_id(), $_SESSION['tainacan_importer'][$id]->collection->get_id() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group importer
|
* @group importer
|
||||||
*/
|
*/
|
||||||
|
@ -164,8 +146,6 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
||||||
$csv_importer = new Importer\CSV();
|
$csv_importer = new Importer\CSV();
|
||||||
$id = $csv_importer->get_id();
|
$id = $csv_importer->get_id();
|
||||||
|
|
||||||
$_SESSION['tainacan_importer'][$id]->set_items_per_step(2);
|
|
||||||
|
|
||||||
// open the file "demosaved.csv" for writing
|
// open the file "demosaved.csv" for writing
|
||||||
$file = fopen($file_name, 'w');
|
$file = fopen($file_name, 'w');
|
||||||
|
|
||||||
|
@ -189,16 +169,16 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
||||||
// Close the file
|
// Close the file
|
||||||
fclose($file);
|
fclose($file);
|
||||||
|
|
||||||
$_SESSION['tainacan_importer'][$id]->set_file( $file_name );
|
$_SESSION['tainacan_importer'][$id]->set_tmp_file( $file_name );
|
||||||
|
|
||||||
// file isset on importer
|
// file isset on importer
|
||||||
$this->assertTrue( isset( $_SESSION['tainacan_importer'][$id]->tmp_file ) );
|
$this->assertTrue( !empty( $_SESSION['tainacan_importer'][$id]->get_tmp_file() ) );
|
||||||
|
|
||||||
// count size of csv
|
// count size of csv
|
||||||
$this->assertEquals( 5, $_SESSION['tainacan_importer'][$id]->get_total_items() );
|
$this->assertEquals( 5, $_SESSION['tainacan_importer'][$id]->get_progress_total_from_source() );
|
||||||
|
|
||||||
// get fields to mapping
|
// get fields to mapping
|
||||||
$headers = $_SESSION['tainacan_importer'][$id]->get_fields();
|
$headers = $_SESSION['tainacan_importer'][$id]->get_source_fields();
|
||||||
$this->assertEquals( $headers[4], 'Column 5' );
|
$this->assertEquals( $headers[4], 'Column 5' );
|
||||||
|
|
||||||
// inserting the collection
|
// inserting the collection
|
||||||
|
@ -212,10 +192,12 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
||||||
),
|
),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
// set the importer
|
$collection_definition = [
|
||||||
$_SESSION['tainacan_importer'][$id]->set_collection( $collection );
|
'id' => $collection->get_id(),
|
||||||
|
'total_items' => $_SESSION['tainacan_importer'][$id]->get_progress_total_from_source(),
|
||||||
|
];
|
||||||
|
|
||||||
// get collection fields to map
|
// get collection fields to map
|
||||||
$fields = $Tainacan_Fields->fetch_by_collection( $collection, [], 'OBJECT' ) ;
|
$fields = $Tainacan_Fields->fetch_by_collection( $collection, [], 'OBJECT' ) ;
|
||||||
|
|
||||||
|
@ -224,32 +206,40 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
||||||
foreach ( $fields as $index => $field ){
|
foreach ( $fields as $index => $field ){
|
||||||
$map[$field->get_id()] = $headers[$index];
|
$map[$field->get_id()] = $headers[$index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$collection_definition['map'] = $map;
|
||||||
|
|
||||||
// set the mapping
|
// add the collection
|
||||||
$_SESSION['tainacan_importer'][$id]->set_mapping( $map );
|
$_SESSION['tainacan_importer'][$id]->add_collection( $collection_definition );
|
||||||
|
|
||||||
// check is equal
|
|
||||||
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_mapping(), $map );
|
|
||||||
|
|
||||||
//execute the process
|
//execute the process
|
||||||
|
$this->assertEquals(1, $_SESSION['tainacan_importer'][$id]->run(), 'first step should import 1 item');
|
||||||
$this->assertEquals(2, $_SESSION['tainacan_importer'][$id]->run(), 'first step should import 2 items');
|
$this->assertEquals(2, $_SESSION['tainacan_importer'][$id]->run(), 'second step should import 2 items');
|
||||||
$this->assertEquals(4, $_SESSION['tainacan_importer'][$id]->run(), 'second step should import 2 items');
|
$this->assertEquals(3, $_SESSION['tainacan_importer'][$id]->run(), 'third step should import 3 items');
|
||||||
$this->assertEquals(5, $_SESSION['tainacan_importer'][$id]->run(), 'third step should import 3 items');
|
$this->assertEquals(4, $_SESSION['tainacan_importer'][$id]->run(), 'third step should import 4 items');
|
||||||
$this->assertEquals(5, $_SESSION['tainacan_importer'][$id]->run(), 'if call run again after finish, do nothing');
|
$this->assertEquals(false, $_SESSION['tainacan_importer'][$id]->run(), '5 items and return false because its finished');
|
||||||
|
$this->assertEquals(false, $_SESSION['tainacan_importer'][$id]->run(), 'if call run again after finish, do nothing');
|
||||||
|
|
||||||
$items = $Tainacan_Items->fetch( [], $collection, 'OBJECT' );
|
$items = $Tainacan_Items->fetch( [], $collection, 'OBJECT' );
|
||||||
|
|
||||||
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_total_items(), count( $items ) );
|
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_progress_total_from_source(), count( $items ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group importer
|
* @group importer
|
||||||
*/
|
*/
|
||||||
public function test_fetch_file(){
|
/*
|
||||||
|
public function test_fetch_file(){
|
||||||
$csv_importer = new Importer\CSV();
|
$csv_importer = new Importer\CSV();
|
||||||
$id = $csv_importer->get_id();
|
$id = $csv_importer->get_id();
|
||||||
$_SESSION['tainacan_importer'][$id]->fetch_from_remote( 'http://localhost/wordpress-test/wp-json' );
|
$_SESSION['tainacan_importer'][$id]->fetch_from_remote( 'http://localhost/wordpress-test/wp-json' );
|
||||||
|
|
||||||
|
if(!isset( $_SESSION['tainacan_importer'][$id]->tmp_file )){
|
||||||
|
#TODO: Remove dependence of web server (see fetch_from_remote)
|
||||||
|
$this->markTestSkipped('This test need a apache installation available.');
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertTrue( isset( $_SESSION['tainacan_importer'][$id]->tmp_file ) );
|
$this->assertTrue( isset( $_SESSION['tainacan_importer'][$id]->tmp_file ) );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue