Merge branch 'feature/product-csv-import-export' into feature/product-parser-match-exporter

This commit is contained in:
Claudio Sanches 2017-05-24 08:56:27 -03:00
commit da7d5786d3
29 changed files with 569 additions and 243 deletions

View File

@ -1 +1 @@
div.woocommerce-message{overflow:hidden;position:relative;border-right-color:#cc99c2!important}div.woocommerce-message p{max-width:700px}.woocommerce-message a.button-primary,p.woocommerce-actions a.button-primary{background:#bb77ae;border-color:#a36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597;color:#fff;text-shadow:0 -1px 1px #a36597,-1px 0 1px #a36597,0 1px 1px #a36597,1px 0 1px #a36597}.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,p.woocommerce-actions a.button-primary:active,p.woocommerce-actions a.button-primary:focus,p.woocommerce-actions a.button-primary:hover{background:#a36597;border-color:#a36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597}.woocommerce-message a.woocommerce-message-close,p.woocommerce-actions a.woocommerce-message-close{position:absolute;top:0;left:0;padding:10px 21px 10px 15px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close::before,p.woocommerce-actions a.woocommerce-message-close::before{position:absolute;top:8px;right:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message a.button-primary,.woocommerce-message a.button-secondary,p.woocommerce-actions a.button-primary,p.woocommerce-actions a.button-secondary{text-decoration:none!important}.woocommerce-message .twitter-share-button,p.woocommerce-actions .twitter-share-button{margin-top:-3px;margin-right:3px;vertical-align:middle}.woocommerce-about-text,p.woocommerce-actions{margin-bottom:1em!important}div.woocommerce-legacy-shipping-notice,div.woocommerce-no-shipping-methods-notice{overflow:hidden;padding:1px 12px}div.woocommerce-legacy-shipping-notice p,div.woocommerce-no-shipping-methods-notice p{position:relative;z-index:1;max-width:700px;line-height:1.5em;margin:12px 0}div.woocommerce-legacy-shipping-notice p.main,div.woocommerce-no-shipping-methods-notice p.main{font-size:1.1em}div.woocommerce-legacy-shipping-notice::before,div.woocommerce-no-shipping-methods-notice::before{content:'\e01b';font-family:WooCommerce;text-align:center;line-height:1;color:#f7f1f6;display:block;width:1em;font-size:20em;top:36px;left:12px;position:absolute}
div.woocommerce-message{overflow:hidden;position:relative;border-right-color:#cc99c2!important}div.woocommerce-message p{max-width:700px}.woocommerce-message a.button-primary,p.woocommerce-actions a.button-primary{background:#bb77ae;border-color:#a36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597;color:#fff;text-shadow:0 -1px 1px #a36597,-1px 0 1px #a36597,0 1px 1px #a36597,1px 0 1px #a36597}.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,p.woocommerce-actions a.button-primary:active,p.woocommerce-actions a.button-primary:focus,p.woocommerce-actions a.button-primary:hover{background:#a36597;border-color:#a36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597}.woocommerce-message a.woocommerce-message-close,p.woocommerce-actions a.woocommerce-message-close{position:absolute;top:0;left:0;padding:10px 21px 10px 15px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close::before,p.woocommerce-actions a.woocommerce-message-close::before{position:absolute;top:8px;right:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message a.button-primary,.woocommerce-message a.button-secondary,p.woocommerce-actions a.button-primary,p.woocommerce-actions a.button-secondary{text-decoration:none!important}.woocommerce-message .twitter-share-button,p.woocommerce-actions .twitter-share-button{margin-top:-3px;margin-right:3px;vertical-align:middle}.woocommerce-about-text,p.woocommerce-actions{margin-bottom:1em!important}div.woocommerce-legacy-shipping-notice,div.woocommerce-no-shipping-methods-notice{overflow:hidden;padding:1px 12px}div.woocommerce-legacy-shipping-notice p,div.woocommerce-no-shipping-methods-notice p{position:relative;z-index:1;max-width:700px;line-height:1.5em;margin:12px 0}div.woocommerce-legacy-shipping-notice p.main,div.woocommerce-no-shipping-methods-notice p.main{font-size:1.1em}div.woocommerce-legacy-shipping-notice::before,div.woocommerce-no-shipping-methods-notice::before{content:'\e01b';font-family:WooCommerce;text-align:center;line-height:1;color:#f7f1f6;display:block;width:1em;font-size:20em;top:36px;left:12px;position:absolute}

View File

@ -1 +1 @@
div.woocommerce-message{overflow:hidden;position:relative;border-left-color:#cc99c2!important}div.woocommerce-message p{max-width:700px}.woocommerce-message a.button-primary,p.woocommerce-actions a.button-primary{background:#bb77ae;border-color:#a36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597;color:#fff;text-shadow:0 -1px 1px #a36597,1px 0 1px #a36597,0 1px 1px #a36597,-1px 0 1px #a36597}.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,p.woocommerce-actions a.button-primary:active,p.woocommerce-actions a.button-primary:focus,p.woocommerce-actions a.button-primary:hover{background:#a36597;border-color:#a36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597}.woocommerce-message a.woocommerce-message-close,p.woocommerce-actions a.woocommerce-message-close{position:absolute;top:0;right:0;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close::before,p.woocommerce-actions a.woocommerce-message-close::before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message a.button-primary,.woocommerce-message a.button-secondary,p.woocommerce-actions a.button-primary,p.woocommerce-actions a.button-secondary{text-decoration:none!important}.woocommerce-message .twitter-share-button,p.woocommerce-actions .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}.woocommerce-about-text,p.woocommerce-actions{margin-bottom:1em!important}div.woocommerce-legacy-shipping-notice,div.woocommerce-no-shipping-methods-notice{overflow:hidden;padding:1px 12px}div.woocommerce-legacy-shipping-notice p,div.woocommerce-no-shipping-methods-notice p{position:relative;z-index:1;max-width:700px;line-height:1.5em;margin:12px 0}div.woocommerce-legacy-shipping-notice p.main,div.woocommerce-no-shipping-methods-notice p.main{font-size:1.1em}div.woocommerce-legacy-shipping-notice::before,div.woocommerce-no-shipping-methods-notice::before{content:'\e01b';font-family:WooCommerce;text-align:center;line-height:1;color:#f7f1f6;display:block;width:1em;font-size:20em;top:36px;right:12px;position:absolute}
div.woocommerce-message{overflow:hidden;position:relative;border-left-color:#cc99c2!important}div.woocommerce-message p{max-width:700px}.woocommerce-message a.button-primary,p.woocommerce-actions a.button-primary{background:#bb77ae;border-color:#a36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597;color:#fff;text-shadow:0 -1px 1px #a36597,1px 0 1px #a36597,0 1px 1px #a36597,-1px 0 1px #a36597}.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,p.woocommerce-actions a.button-primary:active,p.woocommerce-actions a.button-primary:focus,p.woocommerce-actions a.button-primary:hover{background:#a36597;border-color:#a36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a36597}.woocommerce-message a.woocommerce-message-close,p.woocommerce-actions a.woocommerce-message-close{position:absolute;top:0;right:0;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close::before,p.woocommerce-actions a.woocommerce-message-close::before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message a.button-primary,.woocommerce-message a.button-secondary,p.woocommerce-actions a.button-primary,p.woocommerce-actions a.button-secondary{text-decoration:none!important}.woocommerce-message .twitter-share-button,p.woocommerce-actions .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}.woocommerce-about-text,p.woocommerce-actions{margin-bottom:1em!important}div.woocommerce-legacy-shipping-notice,div.woocommerce-no-shipping-methods-notice{overflow:hidden;padding:1px 12px}div.woocommerce-legacy-shipping-notice p,div.woocommerce-no-shipping-methods-notice p{position:relative;z-index:1;max-width:700px;line-height:1.5em;margin:12px 0}div.woocommerce-legacy-shipping-notice p.main,div.woocommerce-no-shipping-methods-notice p.main{font-size:1.1em}div.woocommerce-legacy-shipping-notice::before,div.woocommerce-no-shipping-methods-notice::before{content:'\e01b';font-family:WooCommerce;text-align:center;line-height:1;color:#f7f1f6;display:block;width:1em;font-size:20em;top:36px;right:12px;position:absolute}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5428,6 +5428,10 @@ table.bar_chart {
max-width: 700px;
margin: 40px auto;
.error {
text-align: left;
}
.wc-progress-steps {
padding: 0 0 24px;
margin: 0;
@ -5480,8 +5484,11 @@ table.bar_chart {
.wc-actions {
overflow: hidden;
padding: 0 0 2px;
margin: 0 0 24px;
border-top: 1px solid #eee;
margin: 0;
padding: 23px 24px 24px;
line-height: 3em;
.button {
float: right;
font-size: 1.25em;
@ -5506,6 +5513,10 @@ table.bar_chart {
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597;
}
}
.woocommerce-importer-toggle-advanced-options {
color: #999;
}
}
.woocommerce-exporter,
@ -5513,7 +5524,7 @@ table.bar_chart {
.wc-progress-form-content {
background: #fff;
overflow: hidden;
padding: 24px 24px 0;
padding: 0;
margin: 0 0 16px;
box-shadow: 0 1px 3px rgba(0,0,0,.13);
color: #555;
@ -5521,8 +5532,12 @@ table.bar_chart {
header {
border-bottom: 1px solid #eee;
padding: 0;
margin: 0;
padding: 24px 24px 0;
}
section {
padding: 24px 24px 0;
}
h2 {
@ -5549,25 +5564,73 @@ table.bar_chart {
display: none;
}
.woocommerce-exporter-options th,
.woocommerce-importer-options th {
width: 30%;
}
.woocommerce-importer-options th,
.woocommerce-importer-options td,
.woocommerce-exporter-options th,
.woocommerce-exporter-options td {
vertical-align: top;
line-height: 1.75em;
padding: 0 0 24px 0;
label {
color: #555;
font-weight: normal;
}
input[type="checkbox"] {
margin: 0 4px 0 0;
padding: 7px;
}
input[type="text"],
input[type="number"] {
padding: 7px;
height: auto;
margin: 0;
}
.woocommerce-importer-file-url-field-wrapper {
border: 1px solid #ddd;
-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
background-color: #fff;
color: #32373c;
outline: 0;
line-height: 1;
display: block;
code {
background: none;
font-size: smaller;
padding: 0;
margin: 0;
color: #999;
padding: 7px 0 0 7px;
display: inline-block;
}
input {
font-family: Consolas,Monaco,monospace;
border: 0;
margin: 0;
outline: 0;
box-shadow: none;
display: inline-block;
min-width: 25%;
box-sizing: borde
}
}
}
.woocommerce-exporter-options th,
.woocommerce-importer-options th {
width: 35%;
padding-right: 20px;
}
progress {
width: 100%;
height: 42px;
margin: 24px auto 24px;
margin: 0 auto 24px;
display: block;
-webkit-appearance: none;
border: none;
@ -5606,5 +5669,76 @@ table.bar_chart {
display: none;
}
}
.wc-importer-mapping-table-wrapper,
.wc-importer-error-log {
padding: 0;
}
.wc-importer-mapping-table,
.wc-importer-error-log-table {
margin: 0;
border: 0;
box-shadow: none;
td, th {
border: 0;
padding: 12px;
vertical-align: middle;
select {
width: 100%;
}
}
tbody tr:nth-child(odd) td,
tbody tr:nth-child(odd) th {
background: #fbfbfb;
}
th {
font-weight: bold;
}
td:first-child,
th:first-child {
padding-left: 24px;
}
td:last-child,
th:last-child {
padding-right: 24px;
}
.wc-importer-mapping-table-name {
width: 50%;
.description {
color: #999;
margin-top: 4px;
display: block;
code {
background: none;
padding: 0;
}
}
}
}
.woocommerce-importer-done {
text-align: center;
padding: 48px 24px;
font-size: 1.5em;
line-height: 1.75em;
&::before {
@include icon( '\e015' );
color: #A16696;
position: static;
font-size: 100px;
display: block;
float: none;
margin: 0 0 24px;
}
}
}
}

View File

@ -1 +1 @@
body{background:#f1f1f1;box-shadow:none;margin:100px auto 24px;padding:0}#wc-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wc-logo img{max-width:50%}.wc-auth-content{background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.13);overflow:hidden;padding:24px 24px 0;zoom:1}.wc-auth-content h1,.wc-auth-content h2,.wc-auth-content h3,.wc-auth-content table{border:0;clear:none;color:#666;margin:0 0 24px;padding:0}.wc-auth-content p,.wc-auth-content ul{color:#666;font-size:1em;line-height:1.75em;margin:0 0 24px}.wc-auth-content p{padding:0}.wc-auth-content a{color:#a16696}.wc-auth-content a:focus,.wc-auth-content a:hover{color:#111}.wc-auth-content .wc-auth-login label{color:#999;display:block;margin-bottom:.5em}.wc-auth-content .wc-auth-login input{box-sizing:border-box;font-size:1.3em;padding:.5em;width:100%}.wc-auth-content .wc-auth-login .wc-auth-actions{padding:0}.wc-auth-content .wc-auth-login .wc-auth-actions .wc-auth-login-button{float:none;width:100%}.wc-auth-permissions{list-style:disc inside;padding:0}.wc-auth-permissions li{font-size:1em}.wc-auth-logged-in-as{background:#f5f5f5;border-bottom:2px solid #eee;line-height:70px;margin:0 0 24px;padding:0 0 0 1em}.wc-auth-logged-in-as p{margin:0;line-height:70px}.wc-auth-logged-in-as img{float:right;height:70px;margin:0 0 0 1em}.wc-auth-logged-in-as .wc-auth-logout{float:left}.wc-auth .wc-auth-actions{overflow:hidden;padding-right:24px}.wc-auth .wc-auth-actions .button{background:#f7f7f7;border:1px solid #d7d7d7;box-sizing:border-box;color:#777;float:left;font-size:1.25em;height:auto;line-height:1em;padding:1em 2em;text-align:center;width:50%}.wc-auth .wc-auth-actions .button:focus,.wc-auth .wc-auth-actions .button:hover{background:#fcfcfc}.wc-auth .wc-auth-actions .button-primary{background:#ad6ea1;border-color:#a16696;box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 0 rgba(0,0,0,.15);color:#fff;float:left;opacity:1;text-shadow:0 -1px 1px #8a4f7f,-1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,1px 0 1px #8a4f7f}.wc-auth .wc-auth-actions .button-primary:focus,.wc-auth .wc-auth-actions .button-primary:hover{background:#b472a8;color:#fff}.wc-auth .wc-auth-actions .wc-auth-approve{float:left}.wc-auth .wc-auth-actions .wc-auth-deny{float:right;margin-right:-24px}
body{background:#f1f1f1;box-shadow:none;margin:100px auto 24px;padding:0}#wc-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wc-logo img{max-width:50%}.wc-auth-content{background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.13);overflow:hidden;padding:24px 24px 0;zoom:1}.wc-auth-content h1,.wc-auth-content h2,.wc-auth-content h3,.wc-auth-content table{border:0;clear:none;color:#666;margin:0 0 24px;padding:0}.wc-auth-content p,.wc-auth-content ul{color:#666;font-size:1em;line-height:1.75em;margin:0 0 24px}.wc-auth-content p{padding:0}.wc-auth-content a{color:#a16696}.wc-auth-content a:focus,.wc-auth-content a:hover{color:#111}.wc-auth-content .wc-auth-login label{color:#999;display:block;margin-bottom:.5em}.wc-auth-content .wc-auth-login input{box-sizing:border-box;font-size:1.3em;padding:.5em;width:100%}.wc-auth-content .wc-auth-login .wc-auth-actions{padding:0}.wc-auth-content .wc-auth-login .wc-auth-actions .wc-auth-login-button{float:none;width:100%}.wc-auth-permissions{list-style:disc inside;padding:0}.wc-auth-permissions li{font-size:1em}.wc-auth-logged-in-as{background:#f5f5f5;border-bottom:2px solid #eee;line-height:70px;margin:0 0 24px;padding:0 0 0 1em}.wc-auth-logged-in-as p{margin:0;line-height:70px}.wc-auth-logged-in-as img{float:right;height:70px;margin:0 0 0 1em}.wc-auth-logged-in-as .wc-auth-logout{float:left}.wc-auth .wc-auth-actions{overflow:hidden;padding-right:24px}.wc-auth .wc-auth-actions .button{background:#f7f7f7;border:1px solid #d7d7d7;box-sizing:border-box;color:#777;float:left;font-size:1.25em;height:auto;line-height:1em;padding:1em 2em;text-align:center;width:50%}.wc-auth .wc-auth-actions .button:focus,.wc-auth .wc-auth-actions .button:hover{background:#fcfcfc}.wc-auth .wc-auth-actions .button-primary{background:#ad6ea1;border-color:#a16696;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 0 rgba(0,0,0,.15);color:#fff;float:left;opacity:1;text-shadow:0 -1px 1px #8a4f7f,-1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,1px 0 1px #8a4f7f}.wc-auth .wc-auth-actions .button-primary:focus,.wc-auth .wc-auth-actions .button-primary:hover{background:#b472a8;color:#fff}.wc-auth .wc-auth-actions .wc-auth-approve{float:left}.wc-auth .wc-auth-actions .wc-auth-deny{float:right;margin-right:-24px}

View File

@ -1 +1 @@
body{background:#f1f1f1;box-shadow:none;margin:100px auto 24px;padding:0}#wc-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wc-logo img{max-width:50%}.wc-auth-content{background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.13);overflow:hidden;padding:24px 24px 0;zoom:1}.wc-auth-content h1,.wc-auth-content h2,.wc-auth-content h3,.wc-auth-content table{border:0;clear:none;color:#666;margin:0 0 24px;padding:0}.wc-auth-content p,.wc-auth-content ul{color:#666;font-size:1em;line-height:1.75em;margin:0 0 24px}.wc-auth-content p{padding:0}.wc-auth-content a{color:#a16696}.wc-auth-content a:focus,.wc-auth-content a:hover{color:#111}.wc-auth-content .wc-auth-login label{color:#999;display:block;margin-bottom:.5em}.wc-auth-content .wc-auth-login input{box-sizing:border-box;font-size:1.3em;padding:.5em;width:100%}.wc-auth-content .wc-auth-login .wc-auth-actions{padding:0}.wc-auth-content .wc-auth-login .wc-auth-actions .wc-auth-login-button{float:none;width:100%}.wc-auth-permissions{list-style:disc inside;padding:0}.wc-auth-permissions li{font-size:1em}.wc-auth-logged-in-as{background:#f5f5f5;border-bottom:2px solid #eee;line-height:70px;margin:0 0 24px;padding:0 1em 0 0}.wc-auth-logged-in-as p{margin:0;line-height:70px}.wc-auth-logged-in-as img{float:left;height:70px;margin:0 1em 0 0}.wc-auth-logged-in-as .wc-auth-logout{float:right}.wc-auth .wc-auth-actions{overflow:hidden;padding-left:24px}.wc-auth .wc-auth-actions .button{background:#f7f7f7;border:1px solid #d7d7d7;box-sizing:border-box;color:#777;float:right;font-size:1.25em;height:auto;line-height:1em;padding:1em 2em;text-align:center;width:50%}.wc-auth .wc-auth-actions .button:focus,.wc-auth .wc-auth-actions .button:hover{background:#fcfcfc}.wc-auth .wc-auth-actions .button-primary{background:#ad6ea1;border-color:#a16696;box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 0 rgba(0,0,0,.15);color:#fff;float:right;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f}.wc-auth .wc-auth-actions .button-primary:focus,.wc-auth .wc-auth-actions .button-primary:hover{background:#b472a8;color:#fff}.wc-auth .wc-auth-actions .wc-auth-approve{float:right}.wc-auth .wc-auth-actions .wc-auth-deny{float:left;margin-left:-24px}
body{background:#f1f1f1;box-shadow:none;margin:100px auto 24px;padding:0}#wc-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wc-logo img{max-width:50%}.wc-auth-content{background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.13);overflow:hidden;padding:24px 24px 0;zoom:1}.wc-auth-content h1,.wc-auth-content h2,.wc-auth-content h3,.wc-auth-content table{border:0;clear:none;color:#666;margin:0 0 24px;padding:0}.wc-auth-content p,.wc-auth-content ul{color:#666;font-size:1em;line-height:1.75em;margin:0 0 24px}.wc-auth-content p{padding:0}.wc-auth-content a{color:#a16696}.wc-auth-content a:focus,.wc-auth-content a:hover{color:#111}.wc-auth-content .wc-auth-login label{color:#999;display:block;margin-bottom:.5em}.wc-auth-content .wc-auth-login input{box-sizing:border-box;font-size:1.3em;padding:.5em;width:100%}.wc-auth-content .wc-auth-login .wc-auth-actions{padding:0}.wc-auth-content .wc-auth-login .wc-auth-actions .wc-auth-login-button{float:none;width:100%}.wc-auth-permissions{list-style:disc inside;padding:0}.wc-auth-permissions li{font-size:1em}.wc-auth-logged-in-as{background:#f5f5f5;border-bottom:2px solid #eee;line-height:70px;margin:0 0 24px;padding:0 1em 0 0}.wc-auth-logged-in-as p{margin:0;line-height:70px}.wc-auth-logged-in-as img{float:left;height:70px;margin:0 1em 0 0}.wc-auth-logged-in-as .wc-auth-logout{float:right}.wc-auth .wc-auth-actions{overflow:hidden;padding-left:24px}.wc-auth .wc-auth-actions .button{background:#f7f7f7;border:1px solid #d7d7d7;box-sizing:border-box;color:#777;float:right;font-size:1.25em;height:auto;line-height:1em;padding:1em 2em;text-align:center;width:50%}.wc-auth .wc-auth-actions .button:focus,.wc-auth .wc-auth-actions .button:hover{background:#fcfcfc}.wc-auth .wc-auth-actions .button-primary{background:#ad6ea1;border-color:#a16696;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 0 rgba(0,0,0,.15);color:#fff;float:right;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f}.wc-auth .wc-auth-actions .button-primary:focus,.wc-auth .wc-auth-actions .button-primary:hover{background:#b472a8;color:#fff}.wc-auth .wc-auth-actions .wc-auth-approve{float:right}.wc-auth .wc-auth-actions .wc-auth-deny{float:left;margin-left:-24px}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
*{background:0 0!important;color:#000!important;text-shadow:none!important;-webkit-filter:none!important;filter:none!important;-ms-filter:none!important;font-size:9pt!important;opacity:1;-webkit-transition:none!important}@page{margin:.5cm}#adminmenuback,#adminmenuwrap,#screen-meta-links,#wpadminbar,#wpfooter,.update-nag,.updated,.woo-nav-tab-wrapper,.woocommerce-reports-wide .button,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{display:none}h2 .nav-tab{line-height:14px}.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:5px;line-height:14px}#wpcontent{margin-right:0}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{margin-right:-130px;width:130px;display:block}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding-right:130px}.chart-legend{overflow:hidden;zoom:1}.chart-legend li{padding:.25em .5em!important;box-shadow:none!important;border-bottom:1px solid gray!important}
*{background:0 0!important;color:#000!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important;font-size:9pt!important;opacity:1;-webkit-transition:none!important}@page{margin:.5cm}#adminmenuback,#adminmenuwrap,#screen-meta-links,#wpadminbar,#wpfooter,.update-nag,.updated,.woo-nav-tab-wrapper,.woocommerce-reports-wide .button,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{display:none}h2 .nav-tab{line-height:14px}.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:5px;line-height:14px}#wpcontent{margin-right:0}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{margin-right:-130px;width:130px;display:block}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding-right:130px}.chart-legend{overflow:hidden;zoom:1}.chart-legend li{padding:.25em .5em!important;box-shadow:none!important;border-bottom:1px solid gray!important}

View File

@ -1 +1 @@
*{background:0 0!important;color:#000!important;text-shadow:none!important;-webkit-filter:none!important;filter:none!important;-ms-filter:none!important;font-size:9pt!important;opacity:1;-webkit-transition:none!important}@page{margin:.5cm}#adminmenuback,#adminmenuwrap,#screen-meta-links,#wpadminbar,#wpfooter,.update-nag,.updated,.woo-nav-tab-wrapper,.woocommerce-reports-wide .button,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{display:none}h2 .nav-tab{line-height:14px}.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:5px;line-height:14px}#wpcontent{margin-left:0}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{margin-left:-130px;width:130px;display:block}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding-left:130px}.chart-legend{overflow:hidden;zoom:1}.chart-legend li{padding:.25em .5em!important;box-shadow:none!important;border-bottom:1px solid gray!important}
*{background:0 0!important;color:#000!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important;font-size:9pt!important;opacity:1;-webkit-transition:none!important}@page{margin:.5cm}#adminmenuback,#adminmenuwrap,#screen-meta-links,#wpadminbar,#wpfooter,.update-nag,.updated,.woo-nav-tab-wrapper,.woocommerce-reports-wide .button,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{display:none}h2 .nav-tab{line-height:14px}.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:5px;line-height:14px}#wpcontent{margin-left:0}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{margin-left:-130px;width:130px;display:block}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding-left:130px}.chart-legend{overflow:hidden;zoom:1}.chart-legend li{padding:.25em .5em!important;box-shadow:none!important;border-bottom:1px solid gray!important}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,23 +5,26 @@
* productImportForm handles the import process.
*/
var productImportForm = function( $form ) {
this.$form = $form;
this.xhr = false;
this.mapping = wc_product_import_params.mapping;
this.position = 0;
this.file = wc_product_import_params.file;
this.security = wc_product_import_params.import_nonce;
this.$form = $form;
this.xhr = false;
this.mapping = wc_product_import_params.mapping;
this.position = 0;
this.file = wc_product_import_params.file;
this.update_existing = wc_product_import_params.update_existing;
this.security = wc_product_import_params.import_nonce;
// Number of import successes/failures.
this.imported = 0;
this.failed = 0;
this.updated = 0;
this.skipped = 0;
// Initial state.
this.$form.find('.woocommerce-importer-progress').val( 0 );
this.run_import = this.run_import.bind( this );
//Start importing.
// Start importing.
this.run_import();
};
@ -35,11 +38,12 @@
type: 'POST',
url: ajaxurl,
data: {
action : 'woocommerce_do_ajax_product_import',
position : $this.position,
mapping : $this.mapping,
file : $this.file,
security : $this.security
action : 'woocommerce_do_ajax_product_import',
position : $this.position,
mapping : $this.mapping,
file : $this.file,
update_existing : $this.update_existing,
security : $this.security
},
dataType: 'json',
success: function( response ) {
@ -47,10 +51,12 @@
$this.position = response.data.position;
$this.imported += response.data.imported;
$this.failed += response.data.failed;
$this.updated += response.data.updated;
$this.skipped += response.data.skipped;
$this.$form.find('.woocommerce-importer-progress').val( response.data.percentage );
if ( 'done' === response.data.position ) {
window.location = response.data.url + '&imported=' + parseInt( $this.imported, 10 ) + '&failed=' + parseInt( $this.failed, 10 );
window.location = response.data.url + '&products-imported=' + parseInt( $this.imported, 10 ) + '&products-failed=' + parseInt( $this.failed, 10 ) + '&products-updated=' + parseInt( $this.updated, 10 ) + '&products-skipped=' + parseInt( $this.skipped, 10 );
} else {
$this.run_import();
}

View File

@ -1 +1 @@
!function(a,b){var c=function(a){this.$form=a,this.xhr=!1,this.mapping=wc_product_import_params.mapping,this.position=0,this.file=wc_product_import_params.file,this.security=wc_product_import_params.import_nonce,this.imported=0,this.failed=0,this.$form.find(".woocommerce-importer-progress").val(0),this.run_import=this.run_import.bind(this),this.run_import()};c.prototype.run_import=function(){var c=this;a.ajax({type:"POST",url:ajaxurl,data:{action:"woocommerce_do_ajax_product_import",position:c.position,mapping:c.mapping,file:c.file,security:c.security},dataType:"json",success:function(a){a.success&&(c.position=a.data.position,c.imported+=a.data.imported,c.failed+=a.data.failed,c.$form.find(".woocommerce-importer-progress").val(a.data.percentage),"done"===a.data.position?b.location=a.data.url+"&imported="+parseInt(c.imported,10)+"&failed="+parseInt(c.failed,10):c.run_import())}}).fail(function(a){b.console.log(a)})},a.fn.wc_product_importer=function(){return new c(this),this},a(".woocommerce-importer").wc_product_importer()}(jQuery,window);
!function(a,b){var c=function(a){this.$form=a,this.xhr=!1,this.mapping=wc_product_import_params.mapping,this.position=0,this.file=wc_product_import_params.file,this.update_existing=wc_product_import_params.update_existing,this.security=wc_product_import_params.import_nonce,this.imported=0,this.failed=0,this.updated=0,this.skipped=0,this.$form.find(".woocommerce-importer-progress").val(0),this.run_import=this.run_import.bind(this),this.run_import()};c.prototype.run_import=function(){var c=this;a.ajax({type:"POST",url:ajaxurl,data:{action:"woocommerce_do_ajax_product_import",position:c.position,mapping:c.mapping,file:c.file,update_existing:c.update_existing,security:c.security},dataType:"json",success:function(a){a.success&&(c.position=a.data.position,c.imported+=a.data.imported,c.failed+=a.data.failed,c.updated+=a.data.updated,c.skipped+=a.data.skipped,c.$form.find(".woocommerce-importer-progress").val(a.data.percentage),"done"===a.data.position?b.location=a.data.url+"&products-imported="+parseInt(c.imported,10)+"&products-failed="+parseInt(c.failed,10)+"&products-updated="+parseInt(c.updated,10)+"&products-skipped="+parseInt(c.skipped,10):c.run_import())}}).fail(function(a){b.console.log(a)})},a.fn.wc_product_importer=function(){return new c(this),this},a(".woocommerce-importer").wc_product_importer()}(jQuery,window);

View File

@ -201,25 +201,38 @@ class WC_Admin_Importers {
include_once( WC_ABSPATH . 'includes/admin/importers/class-wc-product-csv-importer-controller.php' );
include_once( WC_ABSPATH . 'includes/import/class-wc-product-csv-importer.php' );
$file = wc_clean( $_POST['file'] );
$file = wc_clean( $_POST['file'] );
$params = array(
'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0,
'mapping' => isset( $_POST['mapping'] ) ? (array) $_POST['mapping'] : array(),
'lines' => apply_filters( 'woocommerce_product_import_batch_size', 10 ),
'parse' => true,
'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0,
'mapping' => isset( $_POST['mapping'] ) ? (array) $_POST['mapping'] : array(),
'update_existing' => isset( $_POST['update_existing'] ) ? (bool) $_POST['update_existing'] : false,
'lines' => apply_filters( 'woocommerce_product_import_batch_size', 10 ),
'parse' => true,
);
$importer = WC_Product_CSV_Importer_Controller::get_importer( $file, $params );
$results = $importer->import();
$percent_complete = $importer->get_percent_complete();
// Log failures.
if ( 0 !== $params['start_pos'] ) {
$error_log = array_filter( (array) get_user_option( 'product_import_error_log' ) );
} else {
$error_log = array();
}
if ( 100 == $percent_complete ) {
$importer = WC_Product_CSV_Importer_Controller::get_importer( $file, $params );
$results = $importer->import();
$percent_complete = $importer->get_percent_complete();
$error_log = array_merge( $error_log, $results['failed'], $results['skipped'] );
update_user_option( get_current_user_id(), 'product_import_error_log', $error_log );
if ( 100 === $percent_complete ) {
wp_send_json_success( array(
'position' => 'done',
'percentage' => 100,
'url' => add_query_arg( array( 'nonce' => wp_create_nonce( 'product-csv' ) ), admin_url( 'edit.php?post_type=product&page=product_importer&step=done' ) ),
'imported' => count( $results['imported'] ),
'failed' => count( $results['failed'] ),
'updated' => count( $results['updated'] ),
'skipped' => count( $results['skipped'] ),
) );
} else {
wp_send_json_success( array(
@ -227,6 +240,8 @@ class WC_Admin_Importers {
'percentage' => $percent_complete,
'imported' => count( $results['imported'] ),
'failed' => count( $results['failed'] ),
'updated' => count( $results['updated'] ),
'skipped' => count( $results['skipped'] ),
) );
}
}

View File

@ -52,6 +52,13 @@ class WC_Product_CSV_Importer_Controller {
*/
protected $delimiter = ',';
/**
* Whether to skip existing products.
*
* @var bool
*/
protected $update_existing = false;
/**
* Get importer instance.
*
@ -92,6 +99,7 @@ class WC_Product_CSV_Importer_Controller {
);
$this->step = isset( $_REQUEST['step'] ) ? sanitize_key( $_REQUEST['step'] ) : current( array_keys( $this->steps ) );
$this->file = isset( $_REQUEST['file'] ) ? wc_clean( $_REQUEST['file'] ) : '';
$this->update_existing = isset( $_REQUEST['update_existing'] ) ? (bool) $_REQUEST['update_existing'] : false;
}
/**
@ -119,10 +127,11 @@ class WC_Product_CSV_Importer_Controller {
}
$params = array(
'step' => $keys[ $step_index + 1 ],
'file' => $this->file,
'delimiter' => $this->delimiter,
'_wpnonce' => wp_create_nonce( 'woocommerce-csv-importer' ), // wp_nonce_url() escapes & to & breaking redirects.
'step' => $keys[ $step_index + 1 ],
'file' => $this->file,
'delimiter' => $this->delimiter,
'update_existing' => $this->update_existing,
'_wpnonce' => wp_create_nonce( 'woocommerce-csv-importer' ), // wp_nonce_url() escapes & to & breaking redirects.
);
return add_query_arg( $params );
@ -162,7 +171,7 @@ class WC_Product_CSV_Importer_Controller {
protected function output_errors() {
if ( $this->errors ) {
foreach ( $this->errors as $error ) {
echo '<p class="error inline">' . esc_html( $error ) . '</p>';
echo '<div class="error inline"><p>' . esc_html( $error ) . '</p></div>';
}
}
}
@ -274,7 +283,7 @@ class WC_Product_CSV_Importer_Controller {
// Check if all fields matches.
if ( 0 === count( array_diff( $mapped_items, $this->get_default_fields() ) ) ) {
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
wp_redirect( esc_url_raw( add_query_arg( array( 'auto_map' => 1 ), $this->get_next_step_link() ) ) );
exit;
}
@ -292,19 +301,24 @@ class WC_Product_CSV_Importer_Controller {
if ( ! empty( $_POST['map_to'] ) ) {
$mapping = wp_unslash( $_POST['map_to'] );
} else {
} elseif ( ! empty( $_GET['auto_map'] ) ) {
// Auto mapping.
$importer = self::get_importer( $this->file, array( 'lines' => 1 ) );
$mapping = $this->auto_map_columns( $importer->get_raw_keys(), false );
} else {
wp_redirect( esc_url_raw( $this->get_next_step_link( 'upload' ) ) );
exit;
}
include_once( dirname( __FILE__ ) . '/views/html-csv-import-progress.php' );
wp_localize_script( 'wc-product-import', 'wc_product_import_params', array(
'import_nonce' => wp_create_nonce( 'wc-product-import' ),
'mapping' => $mapping,
'file' => $this->file,
'import_nonce' => wp_create_nonce( 'wc-product-import' ),
'mapping' => $mapping,
'file' => $this->file,
'update_existing' => $this->update_existing,
) );
wp_enqueue_script( 'wc-product-import' );
include_once( dirname( __FILE__ ) . '/views/html-csv-import-progress.php' );
}
/**
@ -312,29 +326,13 @@ class WC_Product_CSV_Importer_Controller {
* @todo Make this better.
*/
protected function done() {
$imported = isset( $_GET['imported'] ) ? absint( $_GET['imported'] ) : 0;
$failed = isset( $_GET['failed'] ) ? absint( $_GET['failed'] ) : 0;
$imported = isset( $_GET['products-imported'] ) ? absint( $_GET['products-imported'] ) : 0;
$updated = isset( $_GET['products-updated'] ) ? absint( $_GET['products-updated'] ) : 0;
$failed = isset( $_GET['products-failed'] ) ? absint( $_GET['products-failed'] ) : 0;
$skipped = isset( $_GET['products-skipped'] ) ? absint( $_GET['products-skipped'] ) : 0;
$errors = array_filter( (array) get_user_option( 'product_import_error_log' ) );
$results = sprintf(
/* translators: %d: products count */
_n( 'Imported %s product.', 'Imported %s products.', $imported, 'woocommerce' ),
'<strong>' . number_format_i18n( $imported ) . '</strong>'
);
// @todo create a view to display errors or log with WC_Logger.
if ( 0 < $failed ) {
$results .= ' ' . sprintf(
/* translators: %d: products count */
_n( 'Failed %s product.', 'Failed %s products.', $failed, 'woocommerce' ),
'<strong>' . number_format_i18n( $failed ) . '</strong>'
);
}
// Show result.
echo '<div class="updated settings-error"><p>';
/* translators: %d: import results */
printf( __( 'Import complete: %s', 'woocommerce' ), $results );
echo '</p></div>';
include_once( dirname( __FILE__ ) . '/views/html-csv-import-done.php' );
}
/**
@ -432,6 +430,7 @@ class WC_Product_CSV_Importer_Controller {
'external_url' => __( 'External URL', 'woocommerce' ),
'button_text' => __( 'Button text', 'woocommerce' ),
) ) );
$special_columns = array_map(
array( $this, 'sanitize_special_column_name_regex' ),
apply_filters( 'woocommerce_csv_product_import_mapping_special_columns',
@ -486,9 +485,11 @@ class WC_Product_CSV_Importer_Controller {
protected function get_mapping_options( $item = '' ) {
// Get index for special column names.
$index = $item;
if ( preg_match( '/\d+$/', $item, $matches ) ) {
$index = $matches[0];
}
// Properly format for meta field.
$meta = str_replace( 'meta:', '', $item );

View File

@ -0,0 +1,93 @@
<?php
/**
* Admin View: Importer - Done!
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<div class="wc-progress-form-content woocommerce-importer">
<section class="woocommerce-importer-done">
<?php
$results = array();
if ( 0 < $imported ) {
$results[] = sprintf(
/* translators: %d: products count */
_n( '%s product imported', '%s products imported', $imported, 'woocommerce' ),
'<strong>' . number_format_i18n( $imported ) . '</strong>'
);
}
if ( 0 < $updated ) {
$results[] = sprintf(
/* translators: %d: products count */
_n( '%s product updated', '%s products updated', $updated, 'woocommerce' ),
'<strong>' . number_format_i18n( $updated ) . '</strong>'
);
}
if ( 0 < $skipped ) {
$results[] = sprintf(
/* translators: %d: products count */
_n( '%s product was skipped', '%s products were skipped', $skipped, 'woocommerce' ),
'<strong>' . number_format_i18n( $skipped ) . '</strong>'
);
}
if ( 0 < $failed ) {
$results [] = sprintf(
/* translators: %d: products count */
_n( 'Failed to import %s product.', 'Failed to import %s products.', $failed, 'woocommerce' ),
'<strong>' . number_format_i18n( $failed ) . '</strong>'
);
}
if ( 0 < $failed || 0 < $skipped ) {
$results[] = '<a href="#" class="woocommerce-importer-done-view-errors">' . __( 'View import log', 'woocommerce' ) . '</a>';
}
/* translators: %d: import results */
echo wp_kses_post( __( 'Import complete!', 'woocommerce' ) . ' ' . implode( '. ', $results ) );
?>
</section>
<section class="wc-importer-error-log" style="display:none">
<table class="widefat wc-importer-error-log-table">
<thead>
<tr>
<th><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
<th><?php esc_html_e( 'Reason for failure', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php
if ( count( $errors ) ) {
foreach ( $errors as $error ) {
if ( ! is_wp_error( $error ) ) {
continue;
}
$error_data = $error->get_error_data();
?>
<tr>
<th><code><?php echo esc_html( $error_data['row'] ); ?></code></th>
<td><?php echo esc_html( $error->get_error_message() ); ?></td>
</tr>
<?php
}
}
?>
</tbody>
</table>
</section>
<script type="text/javascript">
jQuery(function() {
jQuery( '.woocommerce-importer-done-view-errors' ).on( 'click', function() {
jQuery( '.wc-importer-error-log' ).slideToggle();
return false;
} );
} );
</script>
<div class="wc-actions">
<a class="button button-primary" href="<?php echo esc_url( admin_url( 'edit.php?post_type=product' ) ); ?>"><?php esc_html_e( 'View products', 'woocommerce' ); ?></a>
</div>
</div>

View File

@ -11,45 +11,51 @@ if ( ! defined( 'ABSPATH' ) ) {
<h2><?php esc_html_e( 'Map CSV fields to products', 'woocommerce' ); ?></h2>
<p><?php esc_html_e( 'Select fields from your CSV file to map against products fields, or to ignore during import.', 'woocommerce' ); ?></p>
</header>
<table class="widefat wc-importer__mapping--table">
<thead>
<tr>
<th><?php _e( 'Column name', 'woocommerce' ); ?></th>
<th><?php _e( 'Sample value', 'woocommerce' ); ?></th>
<th><?php _e( 'Map to field', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ( $headers as $index => $name ) : ?>
<?php $mapped_value = $mapped_items[ $index ]; ?>
<section class="wc-importer-mapping-table-wrapper">
<table class="widefat wc-importer-mapping-table">
<thead>
<tr>
<td width="20%"><?php echo esc_html( $name ); ?></td>
<td width="30%"><code><?php echo '' !== ( $sample[ $index ] ) ? esc_html( $sample[ $index ] ) : '-'; ?></code></td>
<td>
<select name="map_to[<?php echo esc_attr( $name ); ?>]">
<option value=""><?php esc_html_e( 'Do not import', 'woocommerce' ); ?></option>
<?php foreach ( $this->get_mapping_options( $mapped_value ) as $key => $value ) : ?>
<?php if ( is_array( $value ) ) : ?>
<optgroup label="<?php echo esc_attr( $value['name'] ); ?>">
<?php foreach ( $value['options'] as $sub_key => $sub_value ) : ?>
<option value="<?php echo esc_attr( $sub_key ); ?>" <?php selected( $mapped_value, $sub_key ); ?>><?php echo esc_html( $sub_value ); ?></option>
<?php endforeach ?>
</optgroup>
<?php else : ?>
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $mapped_value, $key ); ?>><?php echo esc_html( $value ); ?></option>
<?php endif; ?>
<?php endforeach ?>
</select>
</td>
<th><?php _e( 'Column name', 'woocommerce' ); ?></th>
<th><?php _e( 'Map to field', 'woocommerce' ); ?></th>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</thead>
<tbody>
<?php foreach ( $headers as $index => $name ) : ?>
<?php $mapped_value = $mapped_items[ $index ]; ?>
<tr>
<td class="wc-importer-mapping-table-name">
<?php echo esc_html( $name ); ?>
<?php if ( ! empty( $sample[ $index ] ) ) : ?>
<span class="description"><?php _e( 'Sample:', 'woocommerce' ); ?> <code><?php echo esc_html( $sample[ $index ] ); ?></code></span>
<?php endif; ?>
</td>
<td class="wc-importer-mapping-table-field">
<select name="map_to[<?php echo esc_attr( $name ); ?>]">
<option value=""><?php esc_html_e( 'Do not import', 'woocommerce' ); ?></option>
<option value="">--------------</option>
<?php foreach ( $this->get_mapping_options( $mapped_value ) as $key => $value ) : ?>
<?php if ( is_array( $value ) ) : ?>
<optgroup label="<?php echo esc_attr( $value['name'] ); ?>">
<?php foreach ( $value['options'] as $sub_key => $sub_value ) : ?>
<option value="<?php echo esc_attr( $sub_key ); ?>" <?php selected( $mapped_value, $sub_key ); ?>><?php echo esc_html( $sub_value ); ?></option>
<?php endforeach ?>
</optgroup>
<?php else : ?>
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $mapped_value, $key ); ?>><?php echo esc_html( $value ); ?></option>
<?php endif; ?>
<?php endforeach ?>
</select>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</section>
<div class="wc-actions">
<input type="submit" class="button button-primary button-next" value="<?php esc_attr_e( 'Run the importer', 'woocommerce' ); ?>" name="save_step" />
<input type="hidden" name="file" value="<?php echo esc_attr( $this->file ); ?>" />
<input type="hidden" name="delimiter" value="<?php echo esc_attr( $this->delimiter ); ?>" />
<input type="hidden" name="update_existing" value="<?php echo (int) $this->update_existing; ?>" />
<?php wp_nonce_field( 'woocommerce-csv-importer' ); ?>
</div>
</form>

View File

@ -6,13 +6,13 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<div class="wrap woocommerce">
<h1><?php esc_html_e( 'Importing', 'woocommerce' ); ?></h1>
<div class="woocommerce-importer-wrapper">
<form class="woocommerce-importer woocommerce-importer__importing">
<progress class="woocommerce-importer-progress" max="100" value="0"></progress>
</form>
</div>
<div class="wc-progress-form-content woocommerce-importer woocommerce-importer__importing">
<header>
<span class="spinner is-active"></span>
<h2><?php esc_html_e( 'Importing', 'woocommerce' ); ?></h2>
<p><?php esc_html_e( 'Your products are now being imported...', 'woocommerce' ); ?></p>
</header>
<section>
<progress class="woocommerce-importer-progress" max="100" value="0"></progress>
</section>
</div>

View File

@ -11,52 +11,81 @@ if ( ! defined( 'ABSPATH' ) ) {
<h2><?php esc_html_e( 'Import products from a CSV file', 'woocommerce' ); ?></h2>
<p><?php esc_html_e( 'This tool allows you to import (or merge) product data to your store from a CSV file.', 'woocommerce' ); ?></p>
</header>
<table class="form-table woocommerce-importer-options">
<tbody>
<tr>
<th scope="row">
<label for="upload">
<?php _e( 'Choose a file from your computer:', 'woocommerce' ); ?>
</label>
</th>
<td>
<?php
if ( ! empty( $upload_dir['error'] ) ) {
?><div class="inline error"><p><?php esc_html_e( 'Before you can upload your import file, you will need to fix the following error:', 'woocommerce' ); ?></p>
<p><strong><?php echo esc_html( $upload_dir['error'] ); ?></strong></p></div><?php
} else {
?>
<input type="file" id="upload" name="import" size="25" />
<input type="hidden" name="action" value="save" />
<input type="hidden" name="max_file_size" value="<?php echo esc_attr( $bytes ); ?>" />
<br><small><?php
/* translators: %s: maximum upload size */
printf(
__( 'Maximum size: %s', 'woocommerce' ),
$size
);
?></small>
<section>
<table class="form-table woocommerce-importer-options">
<tbody>
<tr>
<th scope="row">
<label for="upload">
<?php _e( 'Choose a CSV file from your computer:', 'woocommerce' ); ?>
</label>
</th>
<td>
<?php
}
?>
</td>
</tr>
<tr>
<th>
<label for="file_url"><?php _e( 'OR enter the path to file on your server:', 'woocommerce' ); ?></label>
</th>
<td>
<code><?php echo esc_html( ABSPATH ) . ' '; ?></code><input type="text" id="file_url" name="file_url" size="25" />
</td>
</tr>
<tr>
<th><label><?php _e( 'CSV Delimiter', 'woocommerce' ); ?></label><br/></th>
<td><input type="text" name="delimiter" placeholder="," size="2" /></td>
</tr>
</tbody>
</table>
if ( ! empty( $upload_dir['error'] ) ) {
?><div class="inline error">
<p><?php esc_html_e( 'Before you can upload your import file, you will need to fix the following error:', 'woocommerce' ); ?></p>
<p><strong><?php echo esc_html( $upload_dir['error'] ); ?></strong></p>
</div><?php
} else {
?>
<input type="file" id="upload" name="import" size="25" />
<input type="hidden" name="action" value="save" />
<input type="hidden" name="max_file_size" value="<?php echo esc_attr( $bytes ); ?>" />
<br><small><?php
/* translators: %s: maximum upload size */
printf(
__( 'Maximum size: %s', 'woocommerce' ),
$size
);
?></small>
<?php
}
?>
</td>
</tr>
<tr>
<th><label for="woocommerce-importer-update-existing"><?php _e( 'Update existing products', 'woocommerce' ); ?></label><br/></th>
<td>
<input type="hidden" name="update_existing" value="0" />
<input type="checkbox" id="woocommerce-importer-update-existing" name="update_existing" value="1" />
<label for="woocommerce-importer-update-existing"><?php esc_html_e( 'If a product being imported matches an existing product ID or SKU, update the existing product data.', 'woocommerce' ); ?></label>
</td>
</tr>
<tr class="woocommerce-importer-advanced hidden">
<th>
<label for="woocommerce-importer-file-url"><?php _e( '<em>or</em> enter the path to a CSV file on your server:', 'woocommerce' ); ?></label>
</th>
<td>
<label for="woocommerce-importer-file-url" class="woocommerce-importer-file-url-field-wrapper">
<code><?php echo esc_html( ABSPATH ) . ' '; ?></code><input type="text" id="woocommerce-importer-file-url" name="file_url" />
</label>
</td>
</tr>
<tr class="woocommerce-importer-advanced hidden">
<th><label><?php _e( 'CSV Delimiter', 'woocommerce' ); ?></label><br/></th>
<td><input type="text" name="delimiter" placeholder="," size="2" /></td>
</tr>
</tbody>
</table>
</section>
<script type="text/javascript">
jQuery(function() {
jQuery( '.woocommerce-importer-toggle-advanced-options' ).on( 'click', function() {
var elements = jQuery( '.woocommerce-importer-advanced' );
if ( elements.is( '.hidden' ) ) {
elements.removeClass( 'hidden' );
jQuery( this ).text( jQuery( this ).data( 'hidetext' ) );
} else {
elements.addClass( 'hidden' );
jQuery( this ).text( jQuery( this ).data( 'showtext' ) );
}
return false;
} );
});
</script>
<div class="wc-actions">
<a href="#" class="woocommerce-importer-toggle-advanced-options" data-hidetext="<?php esc_html_e( 'Hide advanced options', 'woocommerce' ); ?>" data-showtext="<?php esc_html_e( 'Hide advanced options', 'woocommerce' ); ?>"><?php esc_html_e( 'Show advanced options', 'woocommerce' ); ?></a>
<input type="submit" class="button button-primary button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" />
<?php wp_nonce_field( 'woocommerce-csv-importer' ); ?>
</div>

View File

@ -8,7 +8,10 @@ if ( ! defined( 'ABSPATH' ) ) {
wp_enqueue_script( 'wc-product-export' );
$exporter = new WC_Product_CSV_Exporter();
$exporter = new WC_Product_CSV_Exporter();
$product_count = wp_count_posts( 'product' );
$variation_count = wp_count_posts( 'product' );
$total_rows = $product_count->publish + $product_count->private + $variation_count->publish + $variation_count->private;
?>
<div class="wrap woocommerce">
<h1><?php esc_html_e( 'Export Products', 'woocommerce' ); ?></h1>
@ -20,57 +23,56 @@ $exporter = new WC_Product_CSV_Exporter();
<h2><?php esc_html_e( 'Export products to a CSV file', 'woocommerce' ); ?></h2>
<p><?php esc_html_e( 'This tool allows you to generate and download a CSV file containing a list of all products.', 'woocommerce' ); ?></p>
</header>
<table class="form-table woocommerce-exporter-options">
<tbody>
<tr>
<th scope="row">
<label for="woocommerce-exporter-types"><?php esc_html_e( 'Which product types should be exported?', 'woocommerce' ); ?></label>
</th>
<td>
<select id="woocommerce-exporter-types" class="woocommerce-exporter-types wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all', 'woocommerce' ); ?>">
<?php
foreach ( wc_get_product_types() as $value => $label ) {
echo '<option value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
}
?>
<option value="variation"><?php esc_html_e( 'Product variations', 'woocommerce' ); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row">
<label for="woocommerce-exporter-columns"><?php esc_html_e( 'What product data should be exported?', 'woocommerce' ); ?></label>
</th>
<td>
<select id="woocommerce-exporter-columns" class="woocommerce-exporter-columns wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all data', 'woocommerce' ); ?>">
<?php
foreach ( $exporter->get_default_column_names() as $column_id => $column_name ) {
echo '<option value="' . esc_attr( $column_id ) . '">' . esc_html( $column_name ) . '</option>';
}
?>
<option value="downloads"><?php esc_html_e( 'Downloads', 'woocommerce' ); ?></option>
<option value="attributes"><?php esc_html_e( 'Attributes', 'woocommerce' ); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row">
<label for="woocommerce-exporter-meta"><?php esc_html_e( 'Export custom meta data?', 'woocommerce' ); ?></label>
</th>
<td>
<input type="checkbox" id="woocommerce-exporter-meta" value="1" />
<label for="woocommerce-exporter-meta"><?php esc_html_e( 'Yes, export all meta data', 'woocommerce' ); ?></label>
</td>
</tr>
</tbody>
</table>
<section>
<table class="form-table woocommerce-exporter-options">
<tbody>
<tr>
<th scope="row">
<label for="woocommerce-exporter-columns"><?php esc_html_e( 'Which columns should be exported?', 'woocommerce' ); ?></label>
</th>
<td>
<select id="woocommerce-exporter-columns" class="woocommerce-exporter-columns wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all columns', 'woocommerce' ); ?>">
<?php
foreach ( $exporter->get_default_column_names() as $column_id => $column_name ) {
echo '<option value="' . esc_attr( $column_id ) . '">' . esc_html( $column_name ) . '</option>';
}
?>
<option value="downloads"><?php esc_html_e( 'Downloads', 'woocommerce' ); ?></option>
<option value="attributes"><?php esc_html_e( 'Attributes', 'woocommerce' ); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row">
<label for="woocommerce-exporter-types"><?php esc_html_e( 'Which product types should be exported?', 'woocommerce' ); ?></label>
</th>
<td>
<select id="woocommerce-exporter-types" class="woocommerce-exporter-types wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all products', 'woocommerce' ); ?>">
<?php
foreach ( wc_get_product_types() as $value => $label ) {
echo '<option value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
}
?>
<option value="variation"><?php esc_html_e( 'Product variations', 'woocommerce' ); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row">
<label for="woocommerce-exporter-meta"><?php esc_html_e( 'Export custom meta?', 'woocommerce' ); ?></label>
</th>
<td>
<input type="checkbox" id="woocommerce-exporter-meta" value="1" />
<label for="woocommerce-exporter-meta"><?php esc_html_e( 'Yes, export all custom meta', 'woocommerce' ); ?></label>
</td>
</tr>
</tbody>
</table>
<progress class="woocommerce-exporter-progress" max="100" value="0"></progress>
</section>
<div class="wc-actions">
<input type="submit" class="woocommerce-exporter-button button button-primary" value="<?php esc_attr_e( 'Generate CSV', 'woocommerce' ); ?>" />
</div>
<div>
<progress class="woocommerce-exporter-progress" max="100" value="0"></progress>
</div>
</form>
</div>
</div>

View File

@ -128,7 +128,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
return 0;
}
return min( round( ( $this->file_position / $size ) * 100 ), 100 );
return absint( min( round( ( $this->file_position / $size ) * 100 ), 100 ) );
}
/**
@ -138,12 +138,8 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* @return WC_Product|WC_Error
*/
protected function process_item( $data ) {
// Only update.
// @todo
$update_only = false;
try {
$object = $this->prepare_product( $data, $update_only );
$object = $this->prepare_product( $data );
if ( is_wp_error( $object ) ) {
return $object;
@ -182,17 +178,11 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* Prepare a single product for create or update.
*
* @param array $data Row data.
* @param bool $creating If should force create a new product.
* @return WC_Product|WP_Error
*/
protected function prepare_product( $data, $update_only = false ) {
protected function prepare_product( $data ) {
$id = isset( $data['id'] ) ? absint( $data['id'] ) : 0;
// @todo
if ( $update_only && ! $id ) {
return new WP_Error( 'woocommerce_product_importer_product_does_not_exists', __( 'Product does not exists, to create new products disable "Update only" option.', 'woocommerce' ), array( 'status' => 404 ) );
}
// Type is the most important part here because we need to be using the correct class and methods.
if ( isset( $data['type'] ) ) {
$types = array_keys( wc_get_product_types() );
@ -211,6 +201,10 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
$product = new $classname( $id );
} elseif ( isset( $data['id'] ) ) {
$product = wc_get_product( $id );
if ( ! $product ) {
return new WP_Error( 'woocommerce_product_csv_importer_invalid_id', sprintf( __( 'Invalid product ID %d.', 'woocommerce' ), $id ), array( 'id' => $id, 'status' => 401 ) );
}
} else {
$product = new WC_Product_Simple();
}

View File

@ -31,12 +31,13 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
*/
public function __construct( $file, $params = array() ) {
$default_args = array(
'start_pos' => 0, // File pointer start.
'end_pos' => -1, // File pointer end.
'lines' => -1, // Max lines to read.
'mapping' => array(), // Column mapping. csv_heading => schema_heading.
'parse' => false, // Whether to sanitize and format data.
'delimiter' => ',', // CSV delimiter.
'start_pos' => 0, // File pointer start.
'end_pos' => -1, // File pointer end.
'lines' => -1, // Max lines to read.
'mapping' => array(), // Column mapping. csv_heading => schema_heading.
'parse' => false, // Whether to sanitize and format data.
'update_existing' => false, // Whether to update existing items.
'delimiter' => ',', // CSV delimiter.
);
$this->params = wp_parse_args( $params, $default_args );
@ -61,8 +62,8 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
while ( false !== ( $row = fgetcsv( $handle, 0, $this->params['delimiter'] ) ) ) {
$this->raw_data[] = $row;
if ( ( $this->params['end_pos'] > 0 && ftell( $handle ) >= $this->params['end_pos'] ) || 0 === --$this->params['lines'] ) {
break;
if ( ( $this->params['end_pos'] > 0 && ftell( $handle ) >= $this->params['end_pos'] ) || 0 === --$this->params['lines'] ) {
break;
}
}
@ -493,6 +494,31 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
}
}
/**
* Get a string to identify the row from parsed data.
*
* @param array $parsed_data
* @return string
*/
protected function get_row_id( $parsed_data ) {
$id = isset( $parsed_data['id'] ) ? absint( $parsed_data['id'] ) : 0;
$sku = isset( $parsed_data['sku'] ) ? esc_attr( $parsed_data['sku'] ) : '';
$name = isset( $parsed_data['name'] ) ? esc_attr( $parsed_data['name'] ) : '';
$row_data = array();
if ( $name ) {
$row_data[] = $name;
}
if ( $id ) {
$row_data[] = __( 'ID: ', 'woocommerce' ) . $id;
}
if ( $sku ) {
$row_data[] = __( 'SKU: ', 'woocommerce' ) . $sku;
}
return implode( ', ', $row_data );
}
/**
* Process importer.
*
@ -502,13 +528,33 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
$data = array(
'imported' => array(),
'failed' => array(),
'updated' => array(),
'skipped' => array(),
);
foreach ( $this->parsed_data as $parsed_data ) {
foreach ( $this->parsed_data as $parsed_data_key => $parsed_data ) {
// Don't import products with IDs or SKUs that already exist if option is true.
if ( ! $this->params['update_existing'] ) {
$id = isset( $parsed_data['id'] ) ? absint( $parsed_data['id'] ) : 0;
$sku = isset( $parsed_data['sku'] ) ? esc_attr( $parsed_data['sku'] ) : '';
if ( $id && wc_get_product( $id ) ) {
$data['skipped'][] = new WP_Error( 'woocommerce_product_csv_importer_error', __( 'A product with this ID already exists.', 'woocommerce' ), array( 'id' => $id, 'row' => $this->get_row_id( $parsed_data ) ) );
continue;
} elseif ( $sku && wc_get_product_id_by_sku( $sku ) ) {
$data['skipped'][] = new WP_Error( 'woocommerce_product_csv_importer_error', __( 'A product with this SKU already exists.', 'woocommerce' ), array( 'sku' => $sku, 'row' => $this->get_row_id( $parsed_data ) ) );
continue;
}
}
$result = $this->process_item( $parsed_data );
if ( is_wp_error( $result ) ) {
$data['failed'][] = $result;
$result->add_data( array( 'row' => $this->get_row_id( $parsed_data ) ) );
$data['failed'][] = $result;
} elseif ( ! empty( $parsed_data['id'] ) ) {
$data['updated'][] = $result;
} else {
$data['imported'][] = $result;
}